3

mysqli_escape_string最近、パラメトリゼーションとその利点を友人に説明していたところ、彼は、セキュリティの観点よりも優れていると尋ねました。具体的には、入力文字列が (mysqli_escape_string を使用して) エスケープされているにもかかわらず成功する SQL インジェクションの例を思いつきますか?

アップデート:

元の質問で十分に明確でなかったことをお詫びします。ここでの一般的な質問は、入力文字列をエスケープしても SQL インジェクションは可能かということです。

4

2 に答える 2

4

更新された回答

質問は(私の回答が投稿された後)特にターゲットに編集されました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すると、喜んで「引用符をエスケープ」します。これは、。で置き換えることを意味0x270x5c 0x27ます。エンコーディング規則によっては、これにより、マルチバイト文字がを含む別の文字に変更され0x5c 、「残り」0x27が入力にスタンドアロンの一重引用符として残る可能性があります。Voilà、SQLにエスケープされていない引用符を挿入しました。

詳細については、このブログ投稿を参照してください。

于 2012-10-23T08:47:37.603 に答える
4

悪い答え:

具体的には、入力文字列が (mysql_escape_string を使用して) エスケープされているにもかかわらず成功する SQL インジェクションの例を思いつきますか?

確実ではありません。を参照していますがmysql_escape_string()、これは接続エンコーディングを考慮していません (while mysql_real_escape_string()do)。

そのため、慎重に作成された不完全な UTF8 コードポイントが先頭にある、慎重に作成された文字列は、たとえば引用符がエスケープされる可能性がありますが、MySQLはそれを UTF8 文字として「認識する」ためmysql_escape_string() 、エスケープ自体は無視されます。

例えば:

0xC2' OR 1=1 ;--

asによってエスケープさmysql_escape_string()れます

0xC2\' OR 1=1 ;--

に組み立てられる

WHERE password='0xC2\' OR 1=1 ;--';

MySQL からは (適切な接続エンコーディングが有効な場合)、次のように表示されます。

WHERE password='€' OR 1=1 ;[--';]    <-- the bracketed part is considered a comment and ignored

これは古典的な SQL インジェクションです。

しかし、これは、おそらく気を散らすことによって、二重に非推奨の functionを指定したという事実に基づいています。mysql_real_escape_string()

また、これは、サーバーもアプリケーション層 (PHP など) も、入力を生成するときに、いかなる種類の文字セット検証も使用しないことを前提としています。もしそうなら、無効な UTF8 は到着時に削除され、 によって見られることさえありませんmysql_escape_string

本当の答え:

mysql_escape_string(または)は使用しないでくださいmysql_whatever。それらは廃止されており、コードが機能しなくなる可能性があります。代わりに PDO 関数を使用してください。

于 2012-10-23T08:58:53.150 に答える