ASVS 5.0 V15.3.7 requires defenses against HTTP parameter pollution, especially when the framework does not distinguish query string, body, cookie and header parameters. It is Level 2. Read each value from one explicit source, and reject requests that send the same parameter more than once when you expect one.
Why it matters
Different components handle duplicates differently. A gateway may validate the first amount while the application uses the last. Some frameworks merge query and body into one map so a value you expected in the body can be overridden from the URL. Attackers use the mismatch to slip past a check.
How to implement it
Be explicit about source and count:
from flask import request, abort
def single(name):
values = request.form.getlist(name)
if len(values) != 1:
abort(400)
return values[0]
amount = single("amount") # body only, exactly one value
In Express, read req.body for body data, not a merged helper, and check Array.isArray(req.query.id) before use. Where a gateway validates, make sure it and the application parse the same way.
How to test it
Send ?id=1&id=2, a body parameter that is also in the query string with a different value, and a cookie with the same name as a parameter. The app should return 400 or use only the documented source, and validation and processing must see the same value.
Common mistakes
- Using a framework helper that merges every source.
- Validating at the edge and parsing differently behind it.
- Assuming a string and receiving an array.
Quick check
Is picking the first value safe?
Only if every component in the chain also picks the first. Rejecting duplicates avoids the question.