別の質問には、次のようなコメントがあります。
「データベースクエリに関しては、常に準備されたパラメーター化されたクエリを試して使用してください。mysqli および PDO ライブラリはこれをサポートしています。これは、mysql_real_escape_string などのエスケープ関数を使用するよりもはるかに安全です。」
だから、私が聞きたいのは、準備されたパラメーター化されたクエリがより安全なのはなぜですか?
別の質問には、次のようなコメントがあります。
「データベースクエリに関しては、常に準備されたパラメーター化されたクエリを試して使用してください。mysqli および PDO ライブラリはこれをサポートしています。これは、mysql_real_escape_string などのエスケープ関数を使用するよりもはるかに安全です。」
だから、私が聞きたいのは、準備されたパラメーター化されたクエリがより安全なのはなぜですか?
ここにいる人々が見逃していると思う重要な点は、パラメーター化されたクエリをサポートするデータベースでは、心配する必要のある「エスケープ」がないということです。データベースエンジンは、バインドされた変数をSQLステートメントに結合してから、すべてを解析しません。バインドされた変数は個別に保持され、一般的なSQLステートメントとして解析されることはありません。
それがセキュリティとスピードの源です。データベースエンジンは、プレースホルダーにデータのみが含まれていることを認識しているため、完全なSQLステートメントとして解析されることはありません。ステートメントを一度作成してから何度も実行すると、スピードアップが実現します。正規の例は、同じテーブルに複数のレコードを挿入することです。この場合、データベースエンジンは、解析、最適化などを1回だけ行う必要があります。
さて、1つの落とし穴はデータベース抽象化ライブラリです。バインドされた変数を適切なエスケープを使用してSQLステートメントに挿入するだけで偽造されることがあります。それでも、それは自分でやるよりはましです。
1 つは、危険な文字のエスケープをデータベースに任せていることです。これは、人間であるあなたよりもはるかに安全です。
... エスケープを忘れたり、悪意のある SQL を挿入するために使用される可能性のある特殊文字を見逃したりすることはありません。言うまでもなく、起動時のパフォーマンスが向上する可能性があります!
私はセキュリティに非常に精通しているわけではありませんが、次の説明が役立つことを願っています。
次のようなステートメントがあるとします。
mydb から [整数] を選択
それを準備するふりをすると、ステートメントは架空の SQL 実装でバイトにコンパイルされます。
01 00 00 23
Opcode for select Prepared bytes number of "mydb"
for your integer
実行すると、準備されたステートメント用に予約されたスペースに番号が挿入されます。
エスケープを使用するだけの場合と比較すると、そこに意味不明なものを挿入して、メモリがオーバーフローしたり、エスケープするのを忘れた奇妙なSQLコマンドが発生したりする可能性があります。
準備されたステートメントでは、コンテンツをエスケープすることを忘れないためです。したがって、不安を導入する方法はありません。
mysql_real_escape_string は、mysql_query を呼び出すたびに mysql_real_escape_string を使用することを覚えていれば、準備済みステートメントと同じくらい安全ですが、忘れがちです。
最善の場合、そうではないかもしれませんが、少なくとも同等に安全です。そして、なぜチャンスを取るのですか?
このエクスプロイトhttp://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-stringのため、関数は安全ではありません。そのため、プリペアド ステートメントが推奨され、パフォーマンスも向上します。