SentinelScan-WSS / backend /scanners /http_pollution_scanner.py
larxius's picture
Deploy SentinelScan WSS to HF Spaces
d543fc1 verified
Raw
History Blame Contribute Delete
2.55 kB
"""
http_pollution_scanner.py — HTTP Parameter Pollution Scanner
"""
import urllib.request, urllib.error, urllib.parse
from scanners.base_scanner import BaseScanner
class HttpPollutionScanner(BaseScanner):
SCANNER_NAME = "HTTP Parameter Pollution Scanner"
_SCANNER_KEY = "http_pollution"
def __init__(self, scan_id, target, domain, **kwargs):
super().__init__(scan_id, target, domain, **kwargs)
def run(self) -> list:
self.log("INFO", f"[HPP] Testing HTTP Parameter Pollution on {self.target}...")
parsed = urllib.parse.urlparse(self.target)
qs = urllib.parse.parse_qsl(parsed.query)
if not qs:
self.log("INFO", "[HPP] No query parameters to test.")
return self.vulns
baseline = self._fetch(self.target) or ""
for k, v in qs:
# Duplicate the parameter with a different value
dup_qs = urllib.parse.urlencode(qs) + f"&{k}=HPP_PROBE"
test_url = parsed._replace(query=dup_qs).geturl()
resp = self._fetch(test_url)
if resp and "HPP_PROBE" in resp and "HPP_PROBE" not in baseline:
self.add_vuln(
title=f"HTTP Parameter Pollution in `{k}`",
severity="Medium", category="HTTP Parameter Pollution", cvss_score=5.3,
description=f"Duplicating parameter `{k}` with value `HPP_PROBE` caused "
f"the injected value to appear in the response. The server uses the "
f"last/first occurrence, which can bypass WAFs and input validation.",
remediation="Explicitly handle duplicate parameters. Use the first occurrence "
"only and reject requests with duplicate security-sensitive params.")
self.log("WARNING", f"[HPP] Pollution confirmed in `{k}`!")
return self.vulns
self.log("SUCCESS", "[HPP] No HTTP Parameter Pollution detected.")
return self.vulns
def _fetch(self, url):
try:
req = urllib.request.Request(url, headers=self._make_headers())
with urllib.request.urlopen(req, timeout=5, context=self.get_ssl_context()) as r:
return r.read().decode("utf-8", errors="ignore")
except urllib.error.HTTPError as e: return e.read().decode("utf-8", errors="ignore")
except Exception as e:
self.log("ERROR", f"[HPP] _fetch error: {e}")
return self.vulns