-4

以下のスクリプトは、初めての php mysql アプリケーションとして作成しました。私は独学で、コードは意図したとおりに機能します。私のホストは、SQL インジェクション攻撃に対して脆弱である可能性があると考えていますが、改善するために何を変更すべきか、または何を変更すべきかを教えてくれません。私はそれが可能な限りきれいではないと確信していますが、誰かが何か提案や洞察を持っているなら、私は確かにそれを感謝します.

<form  method="post" action="search.php?go"  id="searchform">
      <?php
      $db=mysql_connect ("server",  "*", "*") or die ('I cannot connect  to the database because: ' . mysql_error());
  $mydb=mysql_select_db("*");
$category_sql="SELECT distinct category FROM Members";
$category_Options="";
$category_result=mysql_query($category_sql) or die ('Error: '.mysql_error ());
while ($row=mysql_fetch_array($category_result)) {

    $category=$row["category"];
    $category_Options.="<OPTION VALUE=\"$category\">".$category.'</option>';
}
?>
   <p>
          <SELECT NAME="category"><OPTION VALUE=0>Choose<?=$category_Options?></SELECT>

   </p>
<input name="submit" "id="submit" type="submit" value="submit" />
    </form>


<?php
  if(isset($_POST['submit'])){
  if(isset($_GET['go'])){
  $category=$_POST['category'];
  $category=mysql_real_escape_string($category);
  $sql="SELECT category, company, address, city, state, zip, phone, web, addescription, image
  FROM Members
  WHERE category LIKE '$category'";
$result=mysql_query($sql);
  while($row=mysql_fetch_array($result)){
        $category2=$row["category"];
        $company=$row["company"];
        $address=$row["address"];
        $city=$row["city"];
        $state=$row["state"];
        $zip=$row["zip"];
        $phone=$row["phone"];
        $web = $row["web"];
        $addescription = $row["addescription"];
        $image = $row["image"];
  echo "<blockquote>";
  if(@file_get_contents($image))
{
  echo "<img src='".$image ."' class='image'/>\n";
}
else
{
}
  echo "<p>\n";
  echo "</br>".$category2 . "\n";
  echo "</br><b>".$company . "</b>\n";
  echo "</br>".$address . "\n";
  echo "</br>".$city . ", ".$state. " ".$zip . "\n";
  echo "</br>".$phone . "\n";
  echo "</br><a href=http://".$web .">".$web ."</a>\n";
  echo "</br>".$addescription . "\n";
  echo "</br><a href=http://www.printfriendly.com style=color:#6D9F00;text-decoration:none; class=printfriendly onclick=window.print();return false; title=Printer Friendly and PDF><img style=border:none; src=http://cdn.printfriendly.com/pf-button.gif alt=Print Friendly and PDF/></a>\n";
  echo "</p>";
  echo "</blockquote>"
  ;
 }


  }
  else{
  echo  "<p>Please select a Category</p>";
  }
  }
mysql_close($db)
?>
4

4 に答える 4

3

MySQL 関数は非推奨です。MySQLi 関数と準備済みステートメントを使用することは、SQL インジェクション攻撃から保護するためのより良い方法です。

$stmt = $mysqli->prepare('SELECT category, company, address, city, state, zip, phone, web, addescription, image FROM Members WHERE category LIKE ?');
$stmt->bind_param('s', $category);
于 2013-07-26T15:18:37.763 に答える
1

PDO 接続の実装と、それを使用してクエリを実行する方法を示します。ほら!まず、データベース資格情報を使用して接続変数を作成します。この接続を に保存します$db

$username = "root";
$password = "";
$host = "localhost";
$dbname = "my_database";

$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');

try{
   $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8"; $username, $password, $options);
}catch(PDOException $ex){
   die("Failed to connect: ".$ex->getMessage());
}

$dbこれで、クエリを実行できるPDO 接続が保存されました。PHP 5.4 を使用していない場合は、マジック クォートを考慮する必要があるかもしれません。そのことを覚えておいてください。

それ以外の場合は、次のようにクエリステートメントを作成します..

$query = "SELECT category, company, address, city, state, zip, phone, web, addescription, image FROM Members WHERE category LIKE :category"

その後、$_POST['category']変数から (または$categoryそれを作成してから) 値を parameterにバインドします:category。次のようにします。

$query_params = array( ':category' => $category);

最後に、ステートメントとパラメーターを取得したので、前に作成した$db変数を使用して、ステートメントを準備および実行します。

$statement = $db->prepare($query);
$result = $statement->execute($query_params);

複数の行を返す可能性のあるデータを処理しているSELECTため (カテゴリ内に複数の行があると仮定)、それを考慮する必要があります。ステートメントが返す行を次のように取得します。

$rows = $statement->fetchAll();

$rowこれで、foreach ステートメントを使用して、各データベース テーブル内の列ヘッダーを参照できるようになりました。

$citiesArray = array();
foreach($rows as $row){
   if(isset($row['city'])){
       $citiesArray[] = $row['city'];
   }
}

それが役立つことを願っています!

于 2013-07-26T15:26:09.967 に答える
1

ユーザーを決して信用しないという黄金律を覚えておいてください。セキュリティ上の問題が発生する可能性があるため、未加工のユーザー入力をデータベースに挿入しないでください。

あなたのコードは問題ないようです。ただし、MySQL は PHP 5.5.0 の時点で廃止されていることに注意してください。代わりに、より安全なMySQLiまたはPDO拡張機能を使用する必要があります。

それがあなたのホストがそのようなことを言った理由かもしれませんが、コードをざっと見てみると、私には問題ないように思えました。

乾杯。

于 2013-07-26T15:27:19.827 に答える
0

問題は、コードの次の部分です

$sql = "SELECT category, company, address, city, state, zip,
             phone, web, addescription, image
        FROM Members
        WHERE category LIKE '$category'";
$result=mysql_query($sql);

パラメータ $category が GET または POST パラメータから読み取られる場合は、エスケープする必要があります。

$sql = "SELECT category, company, address, city, state, zip,
             phone, web, addescription, image
        FROM Members
        WHERE category LIKE '" . mysql_real_escape_string($category) . "';";

このように実行している場合、変数はSQL インジェクションに使用できません

ところで (Matthew Johnson が言ったように)、手続き型の mysql 拡張機能は PHP 5.5 以降非推奨です。MysqliまたはPDOを使用することをお勧めします。

OOP の方法 (強く推奨) は次のようになります。

$pdo = new PDO($dsn, $user, $password, $options);
$statement = $pdo->prepareStatement(
    "SELECT category, company, address,
            city, state, zip, phone, web,
            addescription, image
     FROM Members
     WHERE category LIKE :category;");
$statement->bindParam(':category', $category, PDO::PARAM_STR);
$statement->execute();
$categories = $statement->fetchAll();
于 2013-07-26T15:24:41.580 に答える