MySQL APIの関数を使用しています
mysql_real_escape_string()
ドキュメントに基づいて、次の文字をエスケープします。
\0
\n
\r
\
'
"
\Z
今、私はOWASP.orgのESAPIセキュリティライブラリを調べ、Pythonポートに次のコードが含まれていた( http://code.google.com/p/owasp-esapi -python/source/browse/esapi/codecs/mysql.py ):
"""
Encodes a character for MySQL.
"""
lookup = {
0x00 : "\\0",
0x08 : "\\b",
0x09 : "\\t",
0x0a : "\\n",
0x0d : "\\r",
0x1a : "\\Z",
0x22 : '\\"',
0x25 : "\\%",
0x27 : "\\'",
0x5c : "\\\\",
0x5f : "\\_",
}
さて、これらすべての文字が本当にエスケープされる必要があるのかと思っています。 %と_が存在する理由は理解できます。これらはLIKE演算子のメタ文字ですが、バックスペースとタブ文字(\ b\t)が追加された理由を簡単に理解できません。クエリを実行した場合、セキュリティの問題はありますか?
SELECT a FROM b WHERE c = '...user input ...';
ユーザー入力にタブまたはバックスペース文字が含まれている場合は?
私の質問はここにあります。なぜ彼らはESAPIセキュリティライブラリに\ b\tを含めたのですか?これらの文字をエスケープする必要があるかもしれないany状況はありますか?
文字列のMySQLマニュアルページ は次のように述べています。
\0
ASCII NUL(0x00)文字。\'
一重引用符(「'
") キャラクター。\"
二重引用符(「"
") キャラクター。\b
バックスペース文字。\n
改行(ラインフィード)文字。\r
キャリッジリターン文字。\t
タブ文字。\Z
ASCII 26(Control-Z)。表の後の注を参照してください。\\
バックスラッシュ(「\
") キャラクター。\%
A「%
" キャラクター。表の後の注を参照してください。\_
A「_
" キャラクター。表の後の注を参照してください。バックスペース文字に関する推測:「こんにちは、DBを希望どおりに更新するためのクエリです」という電子メールと添付のテキストファイルを
INSERT INTO students VALUES ("Bobby Tables",12,"abc",3.6);
ファイルをcatし、問題がないことを確認して、ファイルをMySQLにパイプするだけです。しかし、あなたが知らなかったことは、
DROP TABLE students;\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b
コンソール出力でバックスペースが上書きしたため、表示されなかったINSERT STATEMENTの前。バム!
ただ、推測です。
編集(抵抗できませんでした):
他のオプションがある場合は、ブラックリスト(悪い文字を識別する)を使用する方法はありません。
ホワイトリストの組み合わせを使用する必要があり、さらに重要なのは、バインドされたパラメーターのアプローチです。
この特定の答えにはPHPフォーカスがありますが、それでも十分に役立ちます。文字列をcharフィルタに通すだけでは多くの場合機能しないことを説明するのに役立ちます。以下を参照してください htmlspecialcharsとmysql_real_escape_stringは私のPHPコードを注入から保護しますか?
ユーザー入力にタブまたはバックスペース文字が含まれている場合は?
今日まで、ほとんどのユーザーがユーザー入力はエスケープする必要があると信じているため、このようなエスケープ "注入を防ぐ"は非常に注目に値する事実です。
Javaソリューション:
public static String filter( String s ) {
StringBuffer buffer = new StringBuffer();
int i;
for( byte b : s.getBytes() ) {
i = (int) b;
switch( i ) {
case 9 : buffer.append( " " ); break;
case 10 : buffer.append( "\\n" ); break;
case 13 : buffer.append( "\\r" ); break;
case 34 : buffer.append( "\\\"" ); break;
case 39 : buffer.append( "\\'" ); break;
case 92 : buffer.append( "\\" );
if( i > 31 && i < 127 ) buffer.append( new String( new byte[] { b } ) );
}
}
return buffer.toString();
}