1

プリペアド ステートメント (パラメーター化されたクエリ) を使用すると、SQL インジェクション攻撃を防ぐために使用できることを学びましたが、この記事で言及されている例外はほとんどありません。.

私の質問は、準備されたステートメントが SQL インジェクションをどのように防ぐのかということです。これまでに学んだこと:

  • パラメーター化されたクエリを使用する場合、クライアントは準備 (最適化) のためにデータなしでクエリをサーバーに送信し、その後、ユーザー データが元のクエリの外に存在するようにパラメーター (ユーザー入力またはその他) がサーバーに送信されます。

  • 準備されたクエリを使用する場合、ユーザー データがエスケープされていないと、SQL インジェクションを防ぐことはできません。

このため、 、 、 を使用するとすべてデータがエスケープされるため、エスケープされていないパラメーターを使用して準備されたステートメントの安全性をテストするために、エスケープされていないデータを送信できないため、この例をテストexecute()できbind_param()ませbinVlaue()binParam()でした。

4

4 に答える 4

4

基本的な問題は次のとおりです。

$value = "Foo' OR 1 = 1 --";
$query = "SELECT id FROM users WHERE name = '$value'";

上記のように連結すると、これが実際のクエリになります。

SELECT id FROM users WHERE name = 'Foo' OR 1 = 1 --'

ここでの問題は、'文字列リテラルのコンテキストで、文字列リテラルを終了するという特別な意味を持つ文字です。

これに対処する 1 つの手法は、文字列リテラルで特別な意味を持つ文字をエスケープすることです。

SELECT id FROM users WHERE name = 'Foo\' OR 1 = 1 --'

もう 1 つの方法は、文字列リテラルを完全に分離することです。そのため、文字列リテラルの開始位置と終了位置について混乱が生じることはありません。

query: SELECT id FROM users WHERE name = $1
   $1: Foo' OR 1 = 1 --

前者の手法はエスケープであり、後者はパラメータ化されたクエリです。そのうちの 1 つだけを使用する必要があります。パラメータ化も行う値をエスケープすると、不要なバックスラッシュで値が台無しになります。

于 2013-09-15T11:38:03.083 に答える