6

最近、1 人のハッカーがスリープ インジェクションを使用して私の Web サイトを遅くしようとしました。mysql_real_escape_string()脆弱な入力のほとんどをカバーするような予防策を使用していますが. クエリ文字列を介して製品の ID を渡し、コマンドを次のようにします。

$id = mysql_real_escape_string($_REQUEST['id']);
$qry = "Select * from products where id = ".$id;

しかし、ハッカーは次のように入力を提供しようとしました

?id=3 and sleep(4)

クエリは次のようになります

Select * from products where id = 3 and sleep(4);

のようないくつかの可能な解決策がありますが

  1. 製品 ID が数値かどうかを確認します
  2. カスタマイズされた関数を使用して、入力からスリープという単語を削除します

これを止める他の方法はありますか?睡眠注射を予防する最善の方法は何ですか?

4

4 に答える 4

21

あなたは正しく逃げていません。SQL文字列mysql_real_escape_string構文を正しくエスケープするためのものですが、値をSQL文字列としてではなく、そのままの値として埋め込むだけです。必要なもの:

$qry = "SELECT * FROM products WHERE id = '$id'";

クエリ内の id を引用符で囲んでいることに注意してください。

ただし、id が数値の場合は、数値にキャストする方が賢明です。

$id = (int)$_GET['id'];
于 2013-01-27T07:30:15.277 に答える
11

SQL インジェクションを防止する最善の方法は、現在のテクノロジを使用することです。MySQLmysql_ファミリの関数は非推奨であり、将来のリビジョンで PHP から削除される予定です。

代わりに、MySQLi または PDO で準備済みステートメントを使用する必要があります。

これらのテクノロジでは、準備されたステートメントとパラメーター化されたクエリが使用されます。SQL ステートメントは、データベース サーバーによってパラメーターとは別に解析されます。攻撃者が悪意のある SQL を挿入することは不可能です。

これを実現するには、基本的に 2 つのオプションがあります。

  1. MySQLi :

    $stmt = $dbConnection->prepare('SELECT * FROM table WHERE name = ?');
    $stmt->bind_param('s', $name);
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        // do something with $row
    }
    
  2. PDO :

    $stmt = $pdo->prepare('SELECT * FROM table WHERE name = :name');
    $stmt->execute(array(':name' => $name));
    foreach ($stmt as $row) {
        // do something with $row
    }
    

何が起こるかというと、渡した SQL ステートメントがprepareデータベース サーバーによって解析およびコンパイルされます。パラメーター (?または のような名前付きパラメーター:name) を指定することにより、データベース エンジンに何をフィルター処理するかを伝えます。次に、準備されたステートメントを呼び出すexecuteと、指定したパラメーター値と組み合わされます。

ここで重要なことは、パラメーター値が SQL 文字列ではなく、コンパイルされたステートメントと結合されることです。SQL インジェクションは、スクリプトが SQL を作成してデータベースに送信するときに、悪意のある文字列を含めるようにスクリプトをだますことによって機能します。したがって、実際の SQL をパラメーターとは別に送信することで、意図しない結果になるリスクを制限できます。プリペアド ステートメントを使用するときに送信するパラメータはすべて文字列として扱われます (ただし、データベース エンジンが最適化を行う場合があるため、パラメータももちろん数値になる可能性があります)。

于 2013-01-27T07:28:47.057 に答える
2

これは間違った質問です。

mysql のインジェクションを防ぐ方法は?」寝るか寝ないかは関係ありません。

そして、この質問にはすでにたくさんの答えがあります

于 2013-01-27T07:30:55.103 に答える
0

PDO または mysqli を使用して、クエリを「準備されたステートメント」に変換する必要があります。

于 2013-01-27T07:30:22.563 に答える