12

を使用してクエリを連結してmysql_real_escape_stringも、SQL インジェクション攻撃から (完全に) 保護されないと述べている人が何人かいます。

mysql_real_escape_stringしかし、あなたを保護しない攻撃を示す入力の例はまだ見ていません。mysql_queryほとんどの例では、 が 1 つのクエリに限定されていることを忘れており、mysql_real_escape_string間違って使用しています。

私が考えることができる唯一の例は次のとおりです。

mysql_query('DELETE FROM users WHERE user_id = '.mysql_real_escape_string($input));

これは、次の入力からあなたを保護しません:

5 OR 1=1

mysql_real_escape_stringこれは、数値ではなく文字列用に設計されているため、欠点ではなく誤った使用法だと思います。数値型にキャストするか、サニタイズ時に入力を文字列として扱う場合は、クエリで同じことを行い、引用符で囲む必要があります。

mysql_real_escape_string数値の誤った処理に依存しない、またはmysql_query1 つのクエリしか実行できないことを忘れないで回避できる入力の例を誰かが提供できますか?

編集:私は制限に興味があり、mysql_real_escape_string代替案と比較するのではなく、新しいプロジェクトにはより良いオプションがあることを認識しており、それに異議を唱えていません.

4

2 に答える 2

6

、または一般的な mysql_ 拡張機能の主な欠点はmysql_real_escape_string、他の最新の API (特に準備済みステートメント) よりも正しく適用するのが難しいことです。mysql_real_escape_string引用符の間の SQL ステートメントで値として使用されるテキスト コンテンツをエスケープする場合です。例えば:

$value = mysql_real_escape_string($value, $link);
$sql = "... `foo` = '$value' ...";
                     ^^^^^^

mysql_real_escape_string$value上記のコンテキストの が SQL 構文を台無しにしないようにします。ここで考えるかもしれないように、それは機能しません:

$sql = "... `foo` = $value ...";

またはここ:

$sql = "... `$value` ...";

またはここ:

$sql = mysql_real_escape_string("... `foo` = '$value' ...");

SQL ステートメント内の引用符で囲まれた文字列以外のコンテキストで使用される値に適用すると、誤って適用され、結果の構文を台無しにしたり、誰かが値を送信して SQL インジェクション攻撃を可能にしたりする可能性があります。の使用例mysql_real_escape_stringは非常に狭いですが、正しく理解されることはめったにありません。

mysql_real_escape_string間違った方法を使用してデータベース接続エンコーディングを設定した場合、お湯に浸る別の方法があります。これを行う必要があります:

mysql_set_charset('utf8', $link);

ただし、これを行うこともできます

mysql_query("SET NAMES 'utf8'", $link);

問題は、後者が mysql_ API をバイパスすることです。これは、latin1(または他の何かを使用して) データベースと通信していると考えています。今使用mysql_real_escape_stringすると、間違った文字エンコーディングとエスケープ文字列が、データベースが後で解釈するのとは異なる方法で想定されます。クエリを実行するSET NAMESと、mysql_ クライアント API が文字列を処理する方法と、データベースがこれらの文字列を解釈する方法との間に亀裂が生じます。これは、特定のマルチバイト文字列の状況でインジェクション攻撃に使用できます。

正しく適用されているかどうかmysql_real_escape_stringを認識しているという点で、根本的なインジェクションの脆弱性はありません。繰り返しになりますが、主な問題は、誤って適用するのが非常に簡単であり、脆弱性が発生することです.

于 2012-10-04T04:40:27.877 に答える
0

わかりました。非推奨になることは別として、存在する可能性のある回避策について知りmysql_*たいと思っていることを理解しています。おそらく、このブログ投稿とスライドはそれらのいくつかを明らかにするかもしれません。しかし、ここでのこの古い質問が示すように、キャストと引用は完全な証拠ではありません。間違っている可能性のあるものは非常にたくさんあり、マーフィーの法則は、これまで有効な「ネットワークを信頼しない」というマントラと結びついて、ひどく間違っています。

おそらくこの記事ですが、最も重要なのは、その記事のフォローアップでさらに多くのセキュリティ問題が明らかになる可能性があることです。正直なところ、mysql_real_escape_string型キャストや文字列形式と組み合わせても、完全に証明できるわけではありません。

printf('WHERE id = \'%d\'',(int)mysql_real_escape_string($_REQUEST['id']));

考えられるすべての攻撃を網羅しているわけではありません。
私はこの問題の専門家ではありませんが、私が言えることは、すべての入力をサニタイズすることであり、どちらかといえば、誤った安心感を与えるでしょ。ほとんどの場合、攻撃から何を、なぜ、どのように保護するかは(最初は)知っていますが、同僚は知らないかもしれません。彼らは何かを忘れるかもしれません、そしてあなたのシステム全体が危険にさらされます。

要約:はい、あらゆる形式の悪意のある入力がDBに到達するのを防ぐことができるかもしれませんが、それが必要とするすべての追加のアクションは追加のリスクです。そのシナリオでは、(いつものように)最大の責任は、月曜日の朝に4杯目のコーヒーを飲んでいない開発者です。どんなに防御的でよく考えられていても、カフェインとニコチンで冷たい七面鳥になり、気性が悪く疲れた開発者であるモンスターから身を守ることができるコードはありません。

于 2012-10-03T07:39:31.053 に答える