彼らがまったく同じことをしない場合、違いは何ですか?MySQLクエリ内の値の区切り文字'
はそうではありませんか?または多分"
しかしそれはまたaddslashesで逃げました。
他のデータベースエンジンでは(そして間違いなくPDOのようなdbラッパー内で)理解していますが、なぜ多くの人がaddslashesの代わりにmysql(i)_escape_stringを使用することに熱心なのですか?
彼らがまったく同じことをしない場合、違いは何ですか?MySQLクエリ内の値の区切り文字'
はそうではありませんか?または多分"
しかしそれはまたaddslashesで逃げました。
他のデータベースエンジンでは(そして間違いなくPDOのようなdbラッパー内で)理解していますが、なぜ多くの人がaddslashesの代わりにmysql(i)_escape_stringを使用することに熱心なのですか?
まず第一に:使用しないでくださいmysql_escape_string
、それは(理由のために)非推奨です!
mysql
拡張機能(非推奨)を介してデータベースに接続するレガシーアプリケーションをサポートする必要がある場合は、mysql_real_escape_string
代わりにを使用してください。それ以外の場合は、すぐにに切り替えmysqli
ます。ここで、プリペアドステートメントとバインドされたパラメーターは、ユーザー入力をエスケープするためのより堅牢なメカニズムを提供します。
とはいえ、答えはとの説明を読むことで見つけることができmysql_real_escape_string
ますaddslashes
:
違い#1
addslashes
MySql接続エンコーディングについては何も知りません。MySql接続で使用されるエンコーディング以外のエンコーディングを表すバイトを含む文字列を渡すと、文字、、、およびの値を持つすべてのバイトを うまくエスケープします。これは、すべての文字、、、および8ビットエンコーディングとUTF-8以外のエンコーディングを使用している場合と同じではない可能性があります。その結果、MySqlによって受信された文字列が破損します。'
"
\
\x00
'
"
\
\x00
このバグをトリガーするには、を使用iconv
して変数をUTF-16に変換してから、でエスケープしてみてaddslashes
ください。データベースが受け取るものを確認します。
addslashes
これが、エスケープに使用すべきでない理由の1つです。
違い#2
とは対照的にaddslashes
、、、、およびのmysql_real_escape_string
文字もエスケープします。MySqlと通信するときは、これらの文字もエスケープする必要があるようです。エスケープしないと、不正な形式のクエリが発生する可能性があります\r
\n
\x1a
addslashes
これが、エスケープに使用すべきでないもう1つの理由です。
Chris Shiflettは、SQLを使用してエスケープすることaddslashes()
が失敗する実際のケースを示してmysql_real_escape_string()
おり、これが唯一の方法です。
これはどのように役立ちますか?MySQLデータベースに対してSQLインジェクション攻撃を試みたい場合、バックスラッシュで一重引用符をエスケープするのは厄介です。ただし、addslashes()を使用している場合は、幸運です。私がする必要があるのは0xbf27のようなものを注入することだけで、addslashes()はこれを0xbf5c27に変更します。これは、有効なマルチバイト文字の後に一重引用符が続きます。言い換えれば、あなたが逃げても、私は一重引用符をうまく挿入することができます。これは、0xbf5cが2文字ではなく1文字として解釈されるためです。おっと、バックスラッシュがあります。
...。
addlashes()を使用しているにもかかわらず、有効なユーザー名またはパスワードを知らなくても正常にログインできます。SQLインジェクションの脆弱性を悪用するだけです。
このタイプの脆弱性を回避するには、mysql_real_escape_string()、プリペアドステートメント、または主要なデータベース抽象化ライブラリのいずれかを使用します。
現在、これは確かにまれなエッジケースですが、データベース固有のエスケープ関数の使用に人々が固執している理由のデモンストレーションです。データベースライブラリだけが、どのような種類のエスケープが必要かを確実に知ることができます。異なるラッパー、文字セット、およびSQLフレーバー(MS SQLサーバーなど)には、異なるエスケープが必要です。その事実を無視することは、脆弱性がどのように生まれるかです。
信頼できないデータからSQLを構築するのではなく、プレースホルダーを使用する必要があるため、どちらも使用しないという点で同じです。
正しい方法で行う方法については、http://bobby-tables.com/php.htmlを参照してください。
それは何よりも文字セットの問題です。データが純粋にASCIIである場合、SQLコマンドと混合されたデータをエスケープするには何addslashes()
で十分でしょうか。ただし、UTF-8エンコーディングのバリエーションに加えて、一部の構成のMySQLでは、UCS2(UTF-16)やGB/Big5中国語文字セットなどのフリンジ文字セットも使用できます。の生のASCIIコードをにエスケープするだけでは不十分です。そして、文字列をエスケープするMySQLの方法は、そもそもSQL標準にあまり準拠していませんでした。MySQLサーバーの将来のリリースで非推奨になる可能性があります。'
\'