当社は、いくつかのツール(Veracode、Appscanなど)を使用して、アプリケーションが最小のセキュリティ要件を満たしていることを確認しています。私はいくつかの欠陥があるレガシーアプリケーションを継承しました。ほとんどの脆弱性を緩和することができましたが、何をしているのかわからないため、次の脆弱性を修正するのに問題があります。私たちのレポートでは、POST変数の1つを次のように変更しているようです
25%27+having+1%3D1--+
これは何で、効果的に何をしていますか?このタイプの攻撃を防ぐにはどうすればよいですか?
この文字列がURLエンコードされた形式からデコードされると、次のようになります。
25' having 1=1--
この文字列は、たとえば次の(PHP)データベースクエリ関数にそのまま配置されます。
mysql_query("SELECT * FROM users WHERE username = '$username'");
これになる:
mysql_query("SELECT * FROM users WHERE username = '25' having 1=1--'");
ここで、%27( ')はWHERE句の引数から抜け出し、ステートメントの実行可能部分を継続することに注意してください。 -の後の1 = 1は、ステートメントの残りを実行されないコメントにします。
SQLのHAVINGステートメントは、GROUP BY演算子を使用するクエリ内で使用されることが想定されており、使用しないクエリでは失敗するはずです。私の推測では、この文字列は、実行されたクエリに配置される無害化されていない変数の存在を簡単にチェックするために使用されていると思います。
このタイプの攻撃を防ぐには、適切な入力サニテーション機能またはパラメーター化されたクエリを使用することをお勧めします。これの実装は、問題のプログラミング環境に依存します。
追加:SQLインジェクションクエリで通常1 = 1を使用すると、すべての行が返され、他のWHERE条件はすべて無効になります。入力例は次のとおりです。
a' OR 1=1 --
次のようなクエリの$ passwordパラメータとして挿入した場合:
SELECT * FROM users WHERE username = '$username' AND password = '$password'
ステートメントは次のようになります。
SELECT * FROM users WHERE username = 'mark' AND password = 'a' OR 1=1 --
1 = 1は常にtrueであるため、結果のデータセットには「users」テーブルのすべてのエントリが含まれます。
かなり標準的なSQLインジェクション攻撃の方法があります。追加されたコードは、アプリケーションで入力が正しく処理されない場合にSQLステートメントを変更する可能性があります(ただし、タイトルからそれを解決したと思います)。 NGS/NCCの この論文 でこのベクトルに言及している問題の適切な説明があります。
問題を緩和するという観点からは、アプリケーションがデータベースへの基になるSQLクエリを変更できないように、アプリケーションへの入力が適切に検証またはエスケープされることを確認する必要があります。
これから始めるのに最適な場所は OWASP SQLインジェクションチートシート です。
パラメータ化されたクエリの代わりに、入力をエスケープすることができます。これをどのように行うか正しくは、プラットフォームとデータベースによって異なります。たとえば、PHPで、mysqlデータベースではmysql_real_escape_string()を使用します。また、これを行う場合は、SQLで数値の場合でも常に単一引用符を使用する必要があります。
あなたはそれを安全にするために文字列の単一引用符を置き換えることができると思うかもしれませんが、それは十分ではありません。単一引用符は他の方法で表すことができます。詳細はこちら: マルチバイト文字のエクスプロイト-PHP/MySQL