0

プリペアド ステートメントの基本的な理解が深まり、SQL インジェクション攻撃を防ぐことができるようになりました。しかし、なぜそれらが上記の攻撃から保護するのかをまだ理解していません. 同様の質問があることは知っていますが、完全に満足のいく答えが見つかりませんでした。

例 - 非常に安全でないコード
したがって、ここにデータベースと通信するための最も基本的な方法があります。

$query = "SELECT * FROM users where id=$username";

保護がなければ、ユーザーは悪意のあるコードを入力し、データベース エンジンを「だまして」壊滅的なクエリを実行することができます。

$username = "1; DROP TABLE users;"
SELECT * FROM users where id=1; DROP TABLE users;

私が理解していないのは、準備されたステートメントがそのようなデータを「除外」する方法です。上記のような SQL クエリを生成するようにデータベースを誘惑しない背後にあるメカニズムは何ですか? 上記の例のセミコロンなど、特定の文字をエスケープするのと同じくらい簡単ですか、それとももっと複雑ですか?

例のように正確なインジェクション攻撃を行い、準備されたステートメントを介して実行した場合、どのようなコマンド文字列がデータベース エンジンに到達するでしょうか?

4

3 に答える 3

1

プリペアド ステートメントは、テキストを追加するだけでなく、それをデータとして送信し、データベースに個別に処理させます。実際には、データベースは実際には SQL ステートメントを使用しないため、それらの「コンパイル済み」バージョンを使用します。

よくわかりませんが、クエリがデータベースに送信される方法にあります。

于 2012-06-26T22:31:54.247 に答える
0

通常、プリペアド ステートメントは、パラメーター バインドを使用するように作成されます。この種の攻撃を遮断するのは、実際にはパラメータ バインディングです。準備済みステートメントを使用せずにパラメーター バインディングを使用できます。

プリペアド ステートメントが提供する 2 番目の保護レベルは、それぞれが単一のステートメントであることです (したがって、 を使用;して 1 つのステートメントから 2 つのステートメントを作成することはできません)。

原則として、インジェクション攻撃から保護するために、準備済みステートメントは、外部入力から派生したものではないデータから準備する必要があります。

于 2012-06-26T22:30:19.017 に答える
0

基本的に、標準の型なしパラメータ バインディングを使用すると、次のようになります。

SELECT * FROM users where id='1; DROP TABLE users;'

データベースでエラーが発生しますが、害はありません。

これはランニングと同じではないことを理解してください

SELECT * FROM users where id='$username' 

を適切にエスケープする$usernameと、DB アクセス スタックの下位層で発生します。

于 2012-06-26T22:32:19.970 に答える