SecureBlockLog inStart a pentest
Vulnerability Repository
MediumInjection

HTTP Parameter Pollution

Supplying duplicate HTTP parameters exploits inconsistent server and WAF parsing to bypass security controls, override logic, and manipulate backend requests.

CVSS 5.3CWE CWE-88OWASP A03:2021 — Injection

Description

HTTP Parameter Pollution (HPP) exploits the fact that the HTTP specification does not define how servers should handle duplicate query string or POST body parameters. Different frameworks, languages, and servers handle this ambiguity in entirely different ways: some take the first value, some take the last value, some concatenate all values with a comma, and some treat the parameter as an array. When a web application and its upstream WAF, reverse proxy, or partner API parse the same request differently, an attacker can craft requests that appear benign to the security layer but deliver a malicious value to the application.

HPP falls under CWE-88 (Argument Injection) and OWASP A03:2021 (Injection) because the attacker is manipulating the argument structure of an HTTP request to inject unintended values. The vulnerability class is particularly relevant in architectures with multiple processing layers — API gateways fronting backend services, WAFs protecting application servers, or frontend services that forward parameters to internal APIs.

HPP is also effective as a logic manipulation technique within a single application: duplicating parameters that represent authorization tokens, user IDs, or transfer amounts can override intended values when the application processes parameters in an unexpected order.

How It Works

WAF bypass example. A WAF blocks requests containing <script> in any parameter:

GET /search?q=<script>alert(1)</script>
→ Blocked by WAF

With HPP, the attacker sends:

GET /search?q=legitimate&q=<script>alert(1)</script>

If the WAF evaluates only the first q value (legitimate) but the application uses the last value (<script>alert(1)</script>), the payload bypasses the WAF and reaches the application.

Authorization bypass example. A funds transfer endpoint uses a to_account parameter. The application processes the last occurrence, but audit logging records the first:

POST /transfer
amount=1000&to_account=ATTACKER_ACCOUNT&to_account=VICTIM_ACCOUNT

The audit log shows the transfer going to the victim's account, while the application actually sends funds to the attacker's account — a parameter override attack.

Server-side HPP in API forwarding. When a frontend service appends parameters to a backend API call:

# Frontend constructs: /api/backend?role=user&USER_SUPPLIED_PARAMS
# Attacker injects: ?role=admin
# Final backend URL: /api/backend?role=user&role=admin

If the backend takes the last role value, the attacker elevates their privilege.

Parameter parsing behavior by platform: PHP ($_GET) takes the last value; ASP.NET takes the first; Node.js/Express with qs creates an array; Flask/Python takes the first; JSP takes all values as an array.

Impact

  • WAF and Security Control Bypass — Smuggling malicious payloads past security filters by exploiting different parameter parsing behavior between the WAF and the application
  • Authorization Logic Bypass — Overriding access control parameters (user IDs, role flags, account numbers) by exploiting which duplicate value the application uses
  • Audit Log Manipulation — Creating discrepancies between what security logs record and what the application actually executed
  • Business Logic Abuse — Manipulating transfer amounts, discount codes, and quantity fields by injecting duplicate parameters

Detection

  1. Duplicate every parameter in key requests — add a second copy of each parameter with a different value (e.g., id=1&id=2) and observe which value the application uses. Test with Burp Suite Repeater.
  2. Test WAF bypass — submit a duplicate parameter where the first value is benign and the second contains a known WAF-blocked payload (e.g., SQL injection syntax). If the payload reaches the application, HPP bypasses the WAF.
  3. Map multi-tier architectures — identify all layers that parse HTTP parameters (WAF, API gateway, application) and test each boundary independently.
  4. Fuzz authorization parameters — duplicate role, user_id, account, admin, and token parameters with escalated values. Verify whether the application enforces authorization based on the expected value.
  5. Test with arrays — send param[]=value1&param[]=value2 and param=value1,value2. Some frameworks interpret these as arrays, which can bypass equality checks.
  6. Review API forwarding code — look for functions that append user-supplied parameters to outbound API URLs or request bodies, which can introduce HPP into downstream services.

Remediation

Use consistent parameter parsing. Define and document which value should be used when duplicate parameters are received (first, last, or reject-if-duplicate) and enforce this uniformly across all layers.

Reject duplicate parameters. The safest approach is to return a 400 Bad Request if the same parameter name appears more than once in a request, eliminating any ambiguity:

// Express.js middleware — reject duplicate parameters
app.use((req, res, next) => {
  const keys = Object.keys(req.query);
  const rawQuery = req.url.split('?')[1] || '';
  const rawKeys = rawQuery.split('&').map(p => p.split('=')[0]);
  const hasDuplicates = rawKeys.length !== new Set(rawKeys).size;
  if (hasDuplicates) return res.status(400).json({ error: 'Duplicate parameters' });
  next();
});

Align WAF and application parsing. Configure the WAF to evaluate all occurrences of a parameter — not just the first or last — when applying security rules.

Validate security-sensitive parameters strictly. For parameters that control authorization (role, user_id, account), validate that exactly one value is present and that it matches the expected format before using it.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping