1

私はビデオ Web サイトのプロジェクトに取り組んでいます。データベースから情報を取得し、必要に応じて詳細を挿入します。

これまでのところすべてが完全に機能していますが、SQL インジェクション テストを行ったところ、すべてが完全にオープンです。私はそれを閉じて物事をもう少し安全にするための答えを探していました.

PDO ステートメントを実装しようとしましたが、理解できません。私は今月 php/sql に取り組んでいるので、非常に新しいです。

以下のコードは、最も脆弱な部分でもあると思われるページの主要な接続ポイントです。

<?php
$username="********"; 
$password="*******";
$database="*******";

$id = $_GET['id']; 
$badchars = array("\"", "\\", "/", "*", "'", "=", "-", "#", ";", "<", ">", "+", "%");
$myid = str_replace($badchars, "", $id); 
mysql_connect('localhost',$username,$password);
@mysql_select_db($database) or die( "Unable to select database");
$result = mysql_query("SELECT * FROM Videos WHERE id='$id'");
while($row = mysql_fetch_array($result)) {
    $title=mysql_result($result,0,"title");
    $url=mysql_result($result,0,"url");
    $id=mysql_result($result,0,"id");
    $description=mysql_result($result,0,"description");
    $source=mysql_result($result,0,"source");
    $type=mysql_result($result,0,'type');
}
?>
4

2 に答える 2

2

PDOを使用するように書き直した例を説明とともに示します。

<?php
$username="********"; 
$password="*******";
$database="*******";

try {
  $pdo = new PDO("mysql:host=localhost;dbname=$database", $username, $password);
} catch (PDOException $e) {
  error_log("PDO connection error: " . $e->getMessage());
  header("Location: http://www.example.com/error.php");
  exit;
}

GET パラメーターを int にキャストできます。これは、数値部分だけを使用し、それ以外を取り除きます。

$id = (int) $_GET['id']; 

動的な値を置換するクエリのプレースホルダーを残します。シンボルで位置パラメータを使用するか、コロン接頭辞構文で名前付きパラメータを使用できます。?

$sql = "SELECT * FROM Videos WHERE id = :id";

prepare() または execute() を呼び出すたびにエラーをテストすることが重要です。

エラーが単純die()にブラウザに白い画面を残すのではなく、可能であれば回復するか、少なくとも友好的な「おっと!」を表示するのが最善です。ユーザーがサイトを引き続き使用できるようにします。

$stmt = $pdo->prepare($sql);
if ($stmt === false) {
  $err = $pdo->errorInfo();
  error_log("PDO prepare error: " . $err[2]);
  header("Location: http://www.example.com/error.php");
  exit;
}

置換するパラメーター値の配列を引数として execute() に渡します。名前付きパラメーターの場合は、連想配列です。位置パラメーターの場合は、単純な序数配列を使用します。

if ($stmt->execute(array(":id"=>$id)) === false) {
  $err = $stmt->errorInfo();
  error_log("PDO execute error: " . $err[2]);
  header("Location: http://www.example.com/error.php");
  exit;
}

次に、ステートメントの結果セットから行ごとに連想配列を取得できます。

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  extract($row);
}

連想配列 $row のキーに基づいて変数 $title、$url などを作成する PHP 組み込み関数であるextract()の使用を示したことに注意してください。しかし、これはあなたのコードに一致させるためだけに行いました。通常、これらのフィールドを参照するだけ$row["title"]です。

于 2013-03-11T20:31:43.740 に答える
-1
$result = mysql_query("SELECT * FROM Videos WHERE id='" . mysql_real_escape_string($_GET['id']) . "'");

...結果の値を大幅に簡素化する mysql_fetch_array() とは対照的に、 mysql_fetch_assoc () の使用を検討することもできます。これらの mysql_result() の呼び出しはまったく必要ありません。

于 2013-03-11T19:45:58.307 に答える