Skip to course content
Free FastAPI backend course

FastAPI for AI Backend Development

Unit 04.04: Parameters that should have been a header

Two commonly misplaced parameters are security problems rather than style ones.

Where it belongs, and what it costs when it does not

Five parameters, three misplaced.

The code sorts them.

MISPLACED = [
    ("?api_key=secret",        "header", "query strings appear in server logs and browser history"),
    ("?user_id=me",            "auth",   "identity comes from the credential, not the caller's claim"),
    ("?format=json",           "header", "Accept: application/json is the standard way"),
    ("?page=2",                "query",  "correctly placed"),
    ("?fields=id,name",        "query",  "correctly placed"),
]
print(f"{'parameter':22} {'belongs in':10} why")
for param, belongs, why in MISPLACED:
    print(f"{param:22} {belongs:10} {why}")

print("""
The first two are security problems rather than style ones. A key in a query
string is written to every access log it passes through, and a user id the
caller supplies is not authentication -- it is a request to be trusted.
""")

A key in a query string is written into every access log it passes through, plus browser history and any Referer header sent onward to a third party. You cannot retract any of those.

The second is subtler. ?user_id=me is the caller telling you who they are, which is not authentication - identity has to come from the credential you verified, or any caller can be any user.

The mistake this prevents

The mistake is accepting an identity parameter because the frontend conveniently has it. The frontend is not a trusted source; anything the client supplies is a request, and identity must be derived from the credential.

Takeaway

Credentials go in headers, never in the query string or path. Identity comes from the verified credential, never from a parameter the caller supplies.