更新された回答
質問は(私の回答が投稿された後)特にターゲットに編集されましたmysqli_escape_string
。これはのエイリアスであるmysql_real_escape_string
ため、接続エンコーディングが考慮されます。これにより、元の回答は適用できなくなりますが、完全を期すために残しておきます。
要するに、新しい答えは、mysqli_escape_string
パラメータ化されたクエリと同じくらいセキュリティ面で優れています。
具体的には、PHPドキュメントページの巨大な警告で、あなたがしてはいけないことが強調されています。
文字セットは、サーバーレベルで設定するか、API関数mysqli_set_charset()
を
使用して設定する必要がありますmysqli_real_escape_string()
。
この警告に注意せずに(つまり、直接SET NAMES
クエリで文字セットを変更した場合)、文字セットをシングルバイトエンコーディングから「便利な」(攻撃者の観点から)マルチバイトエンコーディングに変更すると、次のようになります。事実上、ダムが行うことをエミュレートしmysql_escape_string
ました。入力がどのエンコーディングであるかを知らずに文字をエスケープしようとします。
この状況では、以下の元の回答で説明されているように、SQLインジェクションに対して潜在的に脆弱なままになります。
重要な注意:最近のMySqlバージョンが(クライアントライブラリの)この穴を塞いでいることをどこかで読んだことを覚えています。つまり、脆弱なマルチバイトエンコーディングに切り替えるために使用しても完全に安全である可能性があります。SET NAMES
しかし、私の言葉を信じないでください。
元の回答
とは対照的にmysql_real_escape_string
、ベアは接続エンコーディングmysql_escape_string
を考慮しません。これは、入力がシングルバイトエンコーディングであると想定していることを意味しますが、実際にはマルチバイトエンコーディングである可能性があります。
一部のマルチバイトエンコーディングには、1文字に対応するバイトシーケンスがあり、バイトの1つは一重引用符(0x27
)のASCII値です。このような文字列を入力mysql_escape_string
すると、喜んで「引用符をエスケープ」します。これは、。で置き換えることを意味0x27
し0x5c
0x27
ます。エンコーディング規則によっては、これにより、マルチバイト文字がを含む別の文字に変更され0x5c
、「残り」0x27
が入力にスタンドアロンの一重引用符として残る可能性があります。Voilà、SQLにエスケープされていない引用符を挿入しました。
詳細については、このブログ投稿を参照してください。