二次 SQLi のデモをインターネットで探し回っていますが、まだ見つかりません。多くのサイトでは、それがどのように機能するかを完全に説明していません。短いデモンストレーションを提示する必要があり、Mutillidae を使用して練習しています。誰かが私を正しい方向に導くことができますか?
1 に答える
「二次SQLインジェクション」をGoogleで検索すると、二次SQLインジェクションとは何かについて、多かれ少なかれ関連性のある説明が多数出てきますが、詳細の程度は異なります(あなたが言うように)。
基本的な考え方は、データベースは後で SQL ステートメントに組み込まれるユーザーからのテキストを保存するというものですが、テキストは再利用する前に十分にサニタイズされていません。
ユーザーがデータベースに対してユーザー定義のクエリを作成できるアプリケーションを考えてみてください。簡単な例として、バグ追跡システムがあります。ユーザー定義のクエリ属性の一部は、「バグ ステータスは "クローズ" です」などの単純な条件である場合があります。これは、保存されたクエリ定義を調べることでコーディングできます。
CREATE TABLE UserDefinedQuery
(
...user info...,
bug_status VARCHAR(20),
...other info...
);
SELECT ..., bug_status, ...
INTO ..., hv_bug_status, ...
FROM UserDefinedQuery
WHERE bug_status IS NOT NULL
AND ...other criteria...
wherehv_bug_status
は、バグ ステータス基準を保持するホスト変数 (PHP、C、使用している言語) です。
この値が= 'closed'
の場合、結果の SQL には以下が含まれる可能性があります。
SELECT *
FROM Bugs
WHERE status = 'closed'
AND ...other criteria...
ここで、ユーザーがクエリを定義したときに、代わりに次のように記述したとします。
= 'open' or 1=1
これは、生成されたクエリが次のようになることを意味します。
SELECT *
FROM Bugs
WHERE status = 'open' or 1=1
AND ...other criteria...
が存在OR
すると、クエリの意味が劇的に変化し、ユーザーが意図したものとは異なるあらゆる種類の他のレコードが表示されます。これは、バグ クエリ アプリケーションのバグです。この変更により、CustomerX が、他の顧客 CustomerY および CustomerZ によって報告された、彼らが見るはずのないバグを見ることができる場合、CustomerX は二次 SQL インジェクション攻撃を作成することができました。(インジェクションが単に、関係のないものも含めて必要以上のレコードを表示することを意味する場合、単にバグのあるクエリを作成しただけです。)
明らかに、VARCHAR(20) フィールドでは、致命的な SQL を挿入するためのオプションが制限されています。これは、SQL が冗長な言語であるためです。しかし、基準がより長いフィールドに格納されている場合、「小さなボビー テーブル」が発生する可能性があります。
='';DELETE Bugs;--
(DELETE ステートメントに非標準の短縮形を使用しています。これは 18 文字できしみます。)
どうすればこれを回避できますか? 生成された SQL に含める未加工の SQL フラグメントをユーザーが書き込むことを許可しないでください。UserDefinedQuery.Bug_Status の値をスペース/カンマで区切られた文字列値のリストとして扱い、それに応じてクエリを作成します。
SELECT *
FROM Bugs
WHERE status IN ('=', '''open''', 'or', '1=1')
AND ...other criteria...
クエリは役に立たないかもしれませんが、UserDefinedQuery テーブルのデータによって構造が変更されることはありません。