2

私は準備済みステートメントに精通しており、MySQL インジェクションからの保護に関しては、それらがベスト プラクティスであることを知っています。しかし、この PHP/MySQL ステートメントがどのようにインジェクション攻撃の危険にさらされる可能性があるのか​​ 疑問に思っています。

$result = mysqli_query($db,"SELECT name FROM users WHERE id = '".$_POST['name']."';");

ユーザーからの入力は一重引用符で囲まれているように思えます。mysqli_query1 つのステートメントで複数のクエリを実行できますか?

また、これと同じくらい簡単に上記を安全にしています...

$result = mysqli_query($db,"SELECT name FROM users WHERE id = '".mysqli_real_escape_string($_POST['name'])."';");
4

5 に答える 5

3

ユーザーからの入力は一重引用符で囲まれているように思えます

攻撃者がしなければならないことは、POST データの名前の中に一重引用符を入れることだけです。

name=' OR 1=1

また、これと同じくらい簡単に上記を安全にしています

それは問題ないように見えます...しかし、それは私の目を傷つけます. 準備済みステートメントを使用します。文字列を連結して構築された SQL よりもはるかに読みやすいです。

于 2013-01-14T17:07:06.910 に答える
3

ユーザーからの入力は一重引用符で囲まれているように思えます

name引用符から抜け出すことができるように、posted に一重引用符を含めない限り、そうなります。例: 名前を次のように投稿します。

' or 1 or '

WHERE 句は次のようになります。

WHERE id = '' or 1 or '';

これは、or 1一部のため、テーブル内のすべての行を照合して取得します。ご覧のとおり、引用符から抜け出して SQL を挿入し、引用符に戻ってクエリを有効にしています。

mysqli_query1 つのステートメントで複数のクエリを実行できますか?

いいえ、しかしmysqli_multi_queryyes で実行された場合、最後に複数のクエリを追加できます。

上記を安全にするのと同じくらい簡単mysqli_real_escape_stringですか?

通常はそうですが、Prepared Statement の方が適しています。エスケープを使用すると、WHERE句は次のようになります (上記の例を使用)。

WHERE id = '\' or 1 or \'';

引用符を分割できないため、これはもはや脆弱ではなく、name文字通り一致する場合にのみ行に一致しますが、' or 1 or 'これは明らかにありそうにありません。

于 2013-01-14T17:22:29.963 に答える
1

基本的な説明:

最初の例に従って単純にクエリに挿入すると、変数に単一引用符が含まれている$_POST['name']と、結果の SQL 文字列が無効になります。name

これは、O'Brien などの名前の人をすぐに悩ませます。

しかし、これはハッカーによって悪用される可能性があり、ハッカーは自分の「名前」を変更して、単一引用符の後に有効な SQL コードを含めることができます。これは任意の有効な SQL である可能性があり、ハッカーが DB に対して何かを実行したり、DB から何かをクエリしたりできるようになります。彼ができることは、コード内の他の要因によって異なりますが、最良のシナリオであっても、彼はかなり壊滅的なことを行う可能性があると言えば十分です。

2 番目の質問に答えるには: はい。を使用してエスケープするmysqli_real_escape_string()と、この問題が軽減されます。

ただし、さらに一歩進めるために、mysqli拡張機能の機能である準備済みクエリを使用して調査することもできます。mysqli_real_escape_string()これにより、厄介な長い関数名をあちこちで使用する必要がなくなるため、コードがずっときれいになります。また、クエリ キャッシュの改善など、他の利点もあります。

質問への回答に役立つことを願っています。

于 2013-01-14T17:10:15.200 に答える
0

に次の値を渡すとどうなります$_POST['name']か?

'; DELETE FROM users WHERE name <> '

最初の一重引用符を閉じてから、元のクエリの一重引用符で閉じられる、最後に単一の開いた引用符を持つ有害なクエリを導入します。

2 番目のクエリは問題ありません。準備済みステートメントの使用を検討する必要がありますが (mysqli でサポートされています)。

于 2013-01-14T17:08:11.450 に答える
0

を使用している場合は、これを行うために常にSQL プレースホルダー メソッドを使用mysqliする必要があります。エスケープ関数は難しい方法です。

$stmt = $db->prepare("SELECT name FROM users WHERE id = ?");
$stmt->bind_param('i', $_POST['name']);
$stmt->execute();

ここでのリスクを理解していない場合は、一般的なSQL インジェクション攻撃についてよく読んで、自動化されたハッキン​​グ ツールが十分に注意を払っていない人にどのような影響を与えるかを読む必要があります。

于 2013-01-14T17:09:00.693 に答える