Webアプリケーションへの攻撃手法の多くは「入力値を悪用する」という点で共通しています。その中でも開発者や情シス担当者が見落としがちなのが、同じ名前のパラメータを複数送りつけるという手法です。
フォーム送信やURLのクエリ文字列でパラメータを受け取るWebアプリは、?id=1&id=2 のように同名パラメータが重複して届いたとき、どちらの値を使うかの挙動がフレームワークや言語によって異なります。攻撃者はその「処理の割れ目」を突いて、入力検証をすり抜けたりアクセス制御を回避したりします。
この記事では、HTTPパラメータ汚染(HTTP Parameter Pollution / HPP)の仕組み、攻撃シナリオ、そして開発者・情シス担当者が今すぐ取れる対策を現場目線で解説します。

HTTPパラメータ汚染(HPP)とは?
HTTPパラメータ汚染(HTTP Parameter Pollution、略称HPP)は、HTTPリクエストに同じ名前のパラメータを複数含めることで、サーバーやクライアントの処理を意図しない方向に誘導する攻撃手法です。
HTTPの仕様では、同名パラメータの重複を明確に禁じていません。そのため、Webフレームワークや言語処理系はそれぞれ独自の解釈でこれを処理します。
| 環境 | 重複パラメータの処理 | 例: ?a=1&a=2 |
|---|---|---|
| PHP($_GET) | 後の値が優先 | a = 2 |
| ASP.NET | カンマ区切りで結合 | a = 1,2 |
| Node.js(Express) | 配列として扱う | a = [‘1′,’2’] |
| Java(Servlet) | 最初の値が優先 | a = 1 |
| Python(Django) | 最後の値が優先 | a = 2 |
この処理の非統一性が、攻撃者に悪用できる隙を生み出します。
HPPには大きく2種類あります。
・サーバーサイドHPP(SS-HPP): 攻撃者が細工したリクエストをサーバーに送り、バックエンドのAPIやデータベースクエリへの渡し方を操作する
・クライアントサイドHPP(CS-HPP): Webページがパラメータを読み取ってリンクやフォームを動的に生成する際、重複パラメータによってそのURLやアクションを汚染する
2010年にStefano di PaoloとLuca Carettoniがカンファレンスで発表して以降、OWASP Top 10との関連でも注目を集めています。OWASPの脆弱性分類との関係については、姉妹サイトのOWASP Top 10とは?2021年版の全脆弱性リスト・各項目の意味と対策をわかりやすく解説もあわせて参照してください。
攻撃の仕組み(敵を知る)
HPPがどのように機能するか、代表的なシナリオで見ていきましょう。
1. 入力検証のすり抜け(WAFバイパス)
Webアプリの前段に配置されたWAF(Webアプリケーションファイアウォール)が1つ目のパラメータのみを検査するケースがあります。
# 攻撃者のリクエスト例 GET /search?q=正常なキーワード&q=<script>alert(1)</script> HTTP/1.1 # WAFは最初の q(正常値)のみ検査し、通過と判定 # バックエンドPHPは後の q を採用 → XSSが実行される
WAFが「最初の値しか見ない」実装である場合、2番目に悪意ある値を添えることで検査をすり抜けてしまいます。
2. アクセス制御の回避
ユーザーIDに基づいてアクセス権限をチェックするAPIで、HPPによって権限チェックに使うIDと実際に処理するIDを分離させます。
# 正常リクエスト(自分のID=100のデータ取得) GET /api/data?user_id=100 HTTP/1.1 # HPP攻撃リクエスト GET /api/data?user_id=100&user_id=999 HTTP/1.1 # アクセス制御チェック → 最初の 100(自分のID)→ 通過 # データ取得処理 → 後の 999(他人のID)を使用 → 他者データを閲覧
権限チェックとデータ取得処理が使用するパラメータの取り方が異なるとき、このような「二重人格的」な動作が生まれます。
3. クライアントサイドHPP(URLの汚染)
Webページが現在のURLパラメータを読み取り、リンクを生成する場面で悪用されます。
# 攻撃者が誘導するURL(next=正規のURLパラメータを汚染) https://example.com/redirect?next=/dashboard&next=https://evil.example.com/ # ページのJavaScriptが location.href に後の next を使う実装だと # 正規サイト経由でフィッシングサイトへリダイレクトされる
オープンリダイレクトと組み合わさることで、フィッシング攻撃の信頼性が高まります。
4. バックエンドAPIへのパラメータ注入
フロントエンドがパラメータを受け取ってバックエンドAPIにそのまま転送する構成では、HPPがバックエンドへの追加パラメータ注入に使われることがあります。
# フロントエンドが受け取るリクエスト GET /proxy?action=view&action=admin HTTP/1.1 # フロントエンドが全パラメータを結合してバックエンドに転送すると # バックエンドAPIは "admin" アクションとして解釈してしまう可能性がある
具体的な防御手順
1. 同名パラメータの重複を禁止するバリデーションを実装する
アプリケーション側で受け取ったパラメータに重複がないかチェックし、重複があれば400エラーを返します。
# Python(Flask)での重複パラメータ検出例 from flask import request @app.before_request def check_duplicate_params(): raw_qs = request.query_string.decode('utf-8') seen = {} for pair in raw_qs.split('&'): if '=' in pair: key = pair.split('=')[0] if key in seen: abort(400, "Duplicate parameter detected") seen[key] = True
ただし、意図的に配列渡し(`?ids[]=1&ids[]=2`)を使うAPIでは適用対象を絞る必要があります。
2. フレームワークの「最初の値を使う」動作を意識して実装する
処理するパラメータの値を取得するとき、フレームワークが配列を返す可能性を意識し、常に単一値として扱うよう明示します。
# Node.js(Express)での安全な取得例 # req.query.user_id が配列になる場合に備えて単一値を強制 const userId = Array.isArray(req.query.user_id) ? req.query.user_id[0] // 最初の値のみ使用 : req.query.user_id; # または reject: 配列なら即エラー if (Array.isArray(req.query.user_id)) { return res.status(400).json({ error: 'Invalid parameter' }); }
3. WAFのルールで重複パラメータをブロックする
WAF(ModSecurity等)に、同名パラメータの重複を検出してブロックするルールを追加します。
# ModSecurityルール例(重複パラメータの検出) SecRule ARGS_NAMES "@rx (.*)" \ "id:1001,phase:2,deny,status:400,\ msg:'HTTP Parameter Pollution Attempt',\ t:none,t:urlDecodeUni,\ setvar:tx.param_count.%{MATCHED_VAR}=+1,\ chain" SecRule TX:param_count.%{TX.0} "@gt 1" \ "t:none"
ModSecurityのCRS(Core Rule Set)にもHPP検出ルールが含まれているため、最新版への更新も有効です。
4. アクセス制御とデータ処理で同一のパラメータ取得ロジックを使う
最も根本的な対策は、権限チェックで使うパラメータ取得と、実際のデータ処理で使うパラメータ取得を、同一のロジック・同一のコードで行うことです。コードの二箇所で同名パラメータを異なる方法で取得していないか、コードレビューでチェックします。
5. セキュリティスキャンツールに「HPP検出」オプションを使う
ZAP(OWASP Zed Attack Proxy)にはHPP専用スキャンアドオンがあります。自社のWebアプリに対して定期的にスキャンを実施することで、実装上の漏れを検出できます。
中小企業でも今日からできること
情シス担当者が1人でも取り組める優先度の高い対策をまとめます。
・フレームワークの仕様を確認する: 使用しているWebフレームワーク・言語が重複パラメータをどう処理するか公式ドキュメントで確認し、開発チームに共有する
・外部委託先の開発仕様書を確認する: 「重複パラメータの扱い」についてセキュリティ要件として明記しているか確認する。明記がなければ次の発注時に追記する
・WAFのCRS(コアルールセット)を最新化する: ModSecurityやクラウドWAFでCRSを最新版に保つだけで、多くのHPP攻撃パターンを検出できる
・ペネトレーションテストの対象に追加する: 年次の脆弱性診断に「HPPチェック」を明示的に要件として追加する
・ログで重複パラメータを監視する: アクセスログで同名パラメータが複数含まれるリクエストをgrepして、日常的な観察に組み込む
# アクセスログで重複パラメータを含むリクエストを確認する簡易コマンド例 # Apacheのアクセスログから同名パラメータが疑われるリクエストを抽出 grep -E '(\?|&)([^=&]+)=[^&]*&\2=' /var/log/apache2/access.log | tail -20
よくある誤解と注意点
「HTTPS通信なら安全では?」
HTTPSは通信経路の暗号化であり、リクエストの内容は変わりません。HTTPSを使っていても、攻撃者はリクエストパラメータを自由に操作できます。
「入力バリデーションしているから大丈夫では?」
HPPの巧妙な点は、バリデーション対象のパラメータとデータ処理で実際に使うパラメータが「別の値」になる点にあります。1つ目のパラメータが正規値であればバリデーションは通過します。バリデーションした値と処理に使う値が同一であることを確認してください。
「自動スキャンツールが見つけてくれる」
一般的な脆弱性スキャナはSQLインジェクションやXSSを得意としますが、HPPは処理ロジックの差異に依存するため、ツールが見落とすケースが多くあります。手動テストやHPP専用オプションを使ったスキャンが重要です。
「パラメータは1種類しか渡していない」
意図していなくても、プロキシ・ロードバランサ・APIゲートウェイがリクエストを加工する過程でパラメータが重複するケースがあります。外部からのリクエストだけでなく内部転送時の挙動も確認してください。

本記事のまとめ
HTTPパラメータ汚染(HPP)は、同名パラメータの重複という地味な仕様の差異を突く攻撃手法です。入力検証やWAFをすり抜ける「サイドドア」として悪用されます。
| リスク | 対策 | 優先度 |
|---|---|---|
| WAFバイパス(XSS等) | 重複パラメータ自体を400で拒否 | 高 |
| アクセス制御回避 | 権限チェックと処理で同一の取得ロジックを使う | 高 |
| クライアントサイドHPP | URLパラメータを動的にリンクへ埋め込む実装を見直す | 中 |
| バックエンドAPI注入 | フロントエンドがパラメータを転送する際にホワイトリスト制御 | 中 |
HPPを防ぐ最大のポイントは「パラメータの受け取り方を統一する」ことです。開発・レビュー・テストの各工程でHPPを意識した確認を組み込むことで、このサイドドアを確実に閉められます。
PR
体系的に学ぶ 安全なWebアプリケーションの作り方 第2版(徳丸浩/SBクリエイティブ)
SQLインジェクション・XSS・CSRFからHPPまで、Webアプリの脆弱性を網羅的に解説した定番書。開発者が「なぜ危険なのか」を理解しながら安全な実装を学べる、情シス担当者のコードレビュー観点整理にも役立つ一冊です。
