HTTP Parameter Pollution (HPP) - Parameter-Verschmutzung
HTTP parameter pollution occurs when multiple parameters with the same name are sent in an HTTP request and backend systems interpret them differently. Attackers can use this to bypass validation logic, circumvent WAF rules, and trigger unexpected behavior. Affected: Parameter parsing in PHP (last value), ASP.NET (first value), Node.js (array) – the inconsistency between components is exploited.
HTTP Parameter Pollution (HPP) arises from a quirk of the HTTP standard: there is no normative specification on how web servers should handle duplicate query or body parameters with the same name. Different technologies handle this problem differently—and it is precisely this inconsistency that attackers exploit.
Basic Principle
Problem: What happens with ?id=1&id=2?
PHP (Apache): $_GET['id'] = "2" → last value wins
ASP.NET (IIS): Request["id"] = "1,2" → comma-separated list
JSP (Tomcat): request.getParameter("id") = "1" → first value wins
Node.js (qs): req.query.id = ["1", "2"] → array
Flask (Python): request.args.get("id") = "1" → first value wins
Flask (getlist): request.args.getlist("id") = ["1", "2"] → explicit
The inconsistency IS the problem—not a bug in a component!
Typical HPP attack vectors:
□ Query parameters in GET requests: ?role=user&role;=admin
□ POST body parameters: username=victim&username;=attacker
□ HTTP header values (less common, but possible)
□ JSON arrays in request bodies (JSON HPP)
□ SOAP envelopes with duplicate elements
HPP attack vectors
Attack 1 - WAF Bypass:
WAF checks for SQL injection in parameters:
/search?q=SELECT+*+FROM+users → WAF blocks!
HPP Bypass:
/search?q=SELECT+*&q;=FROM+users → WAF checks only the first parameter
Backend concatenates → Bypass!
Or:
/search?q=1' OR '1'='1 → WAF blocks
/search?q=1'&q;=OR '1'='1 → WAF does not see the complete payload
Backend combines → SQLi possible!
Attack 2 - Signature Verification Bypass:
Typical secure API design (e.g., payment API):
POST /transfer
Body: amount=100&to;=alice&signature;=HMAC(amount=100,to=alice)
HPP attack:
POST /transfer
Body: amount=100&to;=alice&signature;=VALID_HASH&to;=attacker
Problem: Signature verification → takes FIRST "to" value → alice (valid!)
Transfer logic → takes LAST "to" value → attacker (attack!)
→ Valid transfer to the wrong recipient!
Attack 3 - Access Control Bypass:
Application checks authorization:
GET /api/order?user_id=123&status;=pending
HPP bypass:
GET /api/order?user_id=123&user;_id=456&status;=pending
If the authorization layer checks 123 (first value) but
the data query runs with 456 (last value) → IDOR!
→ Third-party orders accessible!
Attack 4 - Logic Manipulation (Order Process):
Apply discount code:
POST /checkout
Body: item_id=EXPENSIVE&coupon;=INVALID&coupon;=VALID50
Coupon validation checks first value → INVALID → no discount applied
Price calculation uses last value → VALID50 → 50% discount!
→ Discount applied without a validated coupon!
Attack 5 - Server-Side HPP (SSHPP):
Backend server aggregates URLs for external API calls:
User input: ⟨=en
Full URL: https://api.intern/data?id=1⟨=en
Attacker submits: &id;=MALICIOUS⟨=en
Full URL: https://api.intern/data?id=1&id;=MALICIOUS⟨=en
→ Internal parameter overwritten!
Detection in the Penetration Test
HPP Testing Methodology:
1. Parameter Identification:
→ List all parameters in GET, POST, cookies, and headers
→ Tip: Burp Suite "Param Miner" Extension
2. Duplication Tests:
For each parameter:
□ Original: ?param=ORIGINAL
□ HPP Test: ?param=ORIGINAL¶m;=INJECTED
□ Reverse order: ?param=INJECTED¶m;=ORIGINAL
□ Comma notation: ?param=ORIGINAL,INJECTED
□ Array notation: ?param[]=ORIGINAL¶m;[]=INJECTED
3. Behavior analysis:
□ Does the app respond differently with duplicated parameters?
□ Which value is actually processed?
□ Are there differences between the validation and processing layers?
4. WAF bypass test:
□ Create a known WAF block (simple SQLi/XSS payload)
□ Split the payload across two parameters
□ Test various combinations
□ Also use array syntax: ?q[]=SELECT&q;[]=*
5. Automated (Burp Active Scan):
→ Parameter duplication is detected by Burp Pro
→ "Passive Scans" often reveal HPP clues in response differences
→ HPP Finder Extension in the BApp Store
6. JSON HPP:
{"user": "alice", "user": "attacker"}
→ Which implementation takes which value?
→ JavaScript parser: last value (usually)
→ Check for "god mode" via JSON duplicates
Mitigation Measures
Prevention against HTTP Parameter Pollution:
1. Consistent parameter extraction:
□ Use ONLY one method for parameter extraction
□ Explicitly decide: first or last value?
□ NEVER rely on implicit framework behavior!
Python (Flask) - safe:
value = request.args.get('param') # first value
values = request.args.getlist('param') # all values
# If getlist returns more than 1 element → 400 Bad Request!
Node.js (Express) - safe:
const param = req.query.param;
if (Array.isArray(param)) {
return res.status(400).json({ error: 'Duplicate parameter' });
}
2. Duplicate rejection:
→ Middleware that blocks duplicate parameters
→ 400 Bad Request for duplicate parameters
Nginx (rudimentary):
if ($args ~* "(.+)=(.*)&\1=") {
return 400;
}
# Warning: Check Regex performance!
3. Consistency between layers:
□ Security checks (WAF/Auth) and the application MUST use the same
parameter semantics
□ Single source of truth for parameter parsing
□ Same library/method for WAF bypass checks and business logic
4. Input whitelisting:
□ Explicitly define expected parameters
□ Discard unknown parameters (do not ignore them!)
□ Validate number of parameters: max. 1 per known name
5. Signature and integrity checks:
□ Calculate HMAC using exactly serialized parameters
□ Canonical serialization: alphabetically sorted key=value pairs
□ Signature verification and processing MUST use the same canonical form
6. WAF configuration:
□ Enable HPP detection in the WAF (ModSecurity: CRS HPP rules)
□ Enable REQUEST_ARGS:duplicate rules
□ Perform periodic bypass tests against your own WAF!
HPP is one of the most frequently overlooked classes of vulnerabilities—because it often arises only through the interaction of multiple components. SSHPP attacks, in which an attacker-controlled parameter overwrites internal API parameters, are particularly dangerous. AWARE7 checks for HPP vulnerabilities during web application penetration tests as part of input validation testing.