http-parameter-pollution について
Webセキュリティテスター向けのHTTP Parameter Pollution(HPP)テストガイドです。リクエスト処理の各層で重複パラメーターがどう解釈されるかに注目し、パーサー差異の検証方法を示します。
主な機能
- 01重複パラメーターの挙動一覧
- 02クエリ、フォーム、JSONのテストパターン
- 03WAF回避とSSRFのシナリオ
- 04CSRFとビジネスロジックのシナリオ
- 05Burp SuiteとOWASP ZAPのテスト指針
- 06生リクエストの順序確認
活用シーン
- 01各リクエスト層の重複キー処理を確認
- 02WAFとバックエンドの解析差を検証
- 03重複パラメーターによるSSRF挙動を評価
- 04決済やアカウント処理のパラメーター曖昧性を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill http-parameter-pollutionインストール後、Claude Code で/http-parameter-pollutionを入力して読み込まれたか確認します。
詳細
スキル:HTTP パラメータ汚染(HPP)
AI 読み込み指示:リクエストの全経路をモデル化してください:ブラウザー → CDN/WAF → リバースプロキシ → アプリケーションフレームワーク → ビジネスコード。重複したキー(
a=1&a=2)は HTTP レベルではエラーではありません。各ホップで先頭の値、最後の値、結合した値、または配列のいずれかとして処理される可能性があります。WAF とアプリケーションの挙動が一致しない場合や、内部 HTTP クライアントがクエリ文字列を再構築する場合は、HPP をテストしてください。ルーティングに関する注意:同じパラメーターが複数回現れる場合や、WAF とバックエンドのスタックが異なる場合は、セクション 1 のマトリックスを使って先頭/最後/結合の前提をテストし、その後、セクション 3 のシナリオチェーンを設計してください。
0. クイックスタート
仮説:セキュリティチェックがパラメーターのある出現箇所を読み取り、アクションが別の出現箇所を読み取ります。
初回のペイロード
id=1&id=2
id=1&id=1%20OR%201=1
url=https://legit.example&id=https://evil.example
amount=1&amount=9999
csrf=TOKEN_A&csrf=TOKEN_B
user=alice&user=admin
ボディのバリエーション(POST で繰り返す)
application/x-www-form-urlencoded
id=1&id=2
multipart/form-data
------boundary
Content-Disposition: form-data; name="id"
1
------boundary
Content-Disposition: form-data; name="id"
2
クイック手法
- ベースラインの
a=1&a=2を使って、フロント側のスタック(CDN/WAF)とオリジン(言語/フレームワーク)を特定します。 - 両方の順序を送信します:
a=1&a=2とa=2&a=1(パーサーによっては順序の影響を受けます)。 - JSON の場合は、重複キーと Content-Type の混同をテストします(セクション 2 を参照)。
1. サーバーの挙動マトリックス
一般的なデフォルトの挙動です。必ず確認してください。ミドルウェアやカスタムパーサーによって上書きされる場合があります。
| 技術 | 挙動 | 例:a=1&a=2 |
|---|---|---|
PHP / Apache($_GET) | 最後の出現箇所 | a=2 |
| ASP.NET / IIS | カンマで結合される場合が多い(すべて) | a=1,2 |
| JSP / Tomcat(サーブレットパラメーター) | 最初の出現箇所 | a=1 |
Python / Django(QueryDict) | 最後の出現箇所 | a=2 |
Python / Flask(request.args) | 最初の出現箇所 | a=1 |
Node.js / Express(req.query) | 値の配列 | a=['1','2'](パーサーのバージョンによって形式が異なる場合があります) |
| Perl / CGI | 最初の出現箇所 | a=1 |
| Ruby / Rack(Rack::Utils) | 最後の出現箇所 | a=2 |
Go net/http(ParseQuery) | 最初の出現箇所 | a=1 |
重要な理由:IIS 上の WAF では 1,2 と認識される一方、PHP のバックエンドでは 2 だけを受け取る場合があります。プロキシが正規化する場合は、その逆もあり得ます。
2. ペイロードのパターン
2.1 基本的な重複キー
GET /api?q=safe&q=evil HTTP/1.1
2.2 配列形式(PHP/一部のフレームワーク)
GET /api?id[]=1&id[]=2 HTTP/1.1
2.3 配列とスカラーの混在
GET /api?item[]=a&item=b HTTP/1.1
2.4 エンコードされたアンパサンド(パーサー間の差異)
# Literal & inside a value vs new pair — depends on decoder
param=value1%26other=value2
param=value1&other=value2
2.5 ネスト/ブラケット形式のキー
GET /api?user[name]=a&user[role]=user&user[role]=admin HTTP/1.1
2.6 JSON の重複キー
{"test":"user","test":"admin"}
多くのパーサーは最後のキーを保持しますが、最初のキーを保持するものもあります。JavaScript の JSON.parse は最後の重複キーを保持します。
3. 攻撃シナリオ
3.1 HPP + WAF バイパス
パターン:WAF は最初の値を検査し、アプリケーションは最後の値を使用します。
id=1&id=1%20UNION%20SELECT%20...
次も試してください:ゲートウェイによるソース間のマージ方法が異なる場合、クエリ文字列内で JSON フィールドの無害な値を重複させます。
3.2 HPP + SSRF
パターン:バリデーターは安全な URL を読み取り、フェッチャーは内部/悪意のある URL を読み取ります。
url=https://allowed.cdn.example/&url=http://169.254.169.254/
どのコンポーネント(ライブラリかアプリケーションか)が、どの出現箇所を処理するか確認してください。
3.3 HPP + CSRF
パターン:アンチ CSRF トークンを重複させ、一方のコピーでパーサー A を、もう一方のコピーでパーサー B を満たします。
csrf=LEGIT&csrf=IGNORED_OR_ALT
状態を変更する対象が明確な、許可済みの CSRF 評価でのみ使用してください。
3.4 HPP + ビジネスロジック(例:決済)
amount=1&amount=5000
quantity=1&quantity=-1
price=9.99&price=0.01
影響を高めるには、競合状態やサーバー側の丸め処理と組み合わせてください。HPP 単独では、多くの場合、各レイヤーでの解釈を分ける必要があります。
4. ツール
| ツール | 使用方法 |
|---|---|
| Burp Suite | Repeater:生のクエリ/ボディに重複キーを追加します。Param Miner/拡張機能で隠れたパラメーターを探し、first と last の解釈によるレスポンスを比較します |
| OWASP ZAP | 手動リクエストエディターを使います。自動スキャンでは HPP を十分にファジングできない場合があるため、手動でバリエーションを試す方法を推奨します |
| カスタムスクリプト | 正確な生の HTTP を構築します(順序を保持します)。一部のクライアントは重複を正規化します |
ヒント:テスト用ラボを管理している場合は、アプリケーションで生のクエリ文字列をログに記録してください。一部のフレームワークでは「採用された」値しか公開されませんが、ログには文字列全体が記録される場合があります。
5. 判断ツリー
+-------------------------+
| Duplicate param name |
| same request |
+------------+------------+
|
+------------------+------------------+
| |
+------v------+ +------v------+
| Single app | | WAF / CDN / |
| layer only | | proxy chain |
+------+------+ +------+------+
| |
+---------v---------+ +---------v---------+
| Read framework | | Map each hop: |
| docs + test | | first/last/join/ |
| a=1&a=2 vs swap | | array |
+---------+---------+ +---------+---------+
| |
+------------------+------------------+
|
+------v------+
| Pick attack |
| template |
+------+------+
|
+-----------+-----------+-----------+-----------+
| | | | |
+----v----+ +----v----+ +----v----+ +----v----+ +----v----+
| WAF vs | | SSRF | | CSRF | | Logic | | JSON |
| app | | split | | token | | numeric | | dup key |
| value | | URL | | confuse | | fields | | parsers |
+---------+ +---------+ +---------+ +---------+ +---------+
安全性と範囲:HPP のテストによって、サーバーの状態(支払い、アカウント設定)が変わる可能性があります。明示的に許可された環境でのみ、対象を限定したアカウントを使用して実行し、影響の大きいリクエストを行う前にパーサーの動作を文書化してください。