In one sentence
HTTP status codes are the three-digit numbers a server returns with every response (200 OK, 404 Not Found, 500 Server Error), and read carefully they leak security-relevant information — whether an account exists, whether you are rate-limited, or whether the server just spilled a stack trace.
Why it matters (the security angle)
Everyone knows 404. The reason status codes earn a place in a security glossary is that the difference between two codes is often an information leak or a control. This page is deliberately not a full HTTP reference — it is the security reading of the codes a pentester, a SOC analyst and an API defender actually reason about.
The classic example is authentication. A login that returns 401 Unauthorized for "wrong password" but 403 Forbidden or a different code for "no such user" hands an attacker a username oracle: they can enumerate valid accounts by watching which code comes back, without ever guessing a password. The same logic runs through status codes everywhere — they are a side channel, and reading them precisely is a real skill.
The classes, and what each leaks
Codes group into five classes; here is the security-relevant behaviour of each:
- 3xx (redirects) — a
302/307whose target comes from user input is the open-redirect bug:?next=https://evil.exampleturns your trusted domain into a phishing springboard, and it is a common step in OAuth token theft. Redirects are also where a downgrade tohttp://can be slipped in — the reason HSTS exists. - 401 vs 403 — 401 means "not authenticated" (who are you?); 403 means "authenticated but not allowed" (I know who you are, no). Mixing them up, or letting the pair distinguish "wrong password" from "unknown user", leaks account existence.
- 429 Too Many Requests — not really an error but a control: it is how rate limiting answers brute-force and credential-stuffing. Its absence under a flood of failed logins is itself a finding.
- 5xx (server errors) — a
500that returns a stack trace, SQL error or framework version is information disclosure; production should return a generic body and log the detail server-side.
Two more habits: verbose codes aid enumeration (a 200 vs 404 difference maps out which files or IDs exist), and any code can be forged by an intermediary — trust the code plus the body plus the headers together, never the number alone.
Try it yourself hands-on
Look codes up for their meaning, then probe how a real endpoint uses them.
- Open the HTTP Status Codes reference and filter to 4xx Client Error. Compare
401("authentication required") with403("server refuses to authorize") and note429is described as rate limiting / DDoS protection — the security framing above, in one glance. Search3xxand read the redirect codes with the open-redirect trap in mind. - Now test behaviour, not just definitions: with the HTTP Request Builder, send a request to your own endpoint with a bad password, then with a non-existent user, and compare the status codes. If they differ, you have found a username oracle — a real finding for the report.
- Hammer a login endpoint (one you own) a few times and check whether a
429ever appears. No 429 under repeated failures means no rate limiting — a brute-force gap worth flagging. - Round out the response-security picture with the HTTP Security Headers Grader: the same responses should also carry the right security headers (HSTS, CSP), so you fix the status-code and header story together.
Result: you read status codes as a security signal — auth enumeration, missing rate limiting, open redirects, leaky 500s — instead of just "the site returned an error".
Common misreadings
- Don't let 401/403 leak existence. For unauthenticated flows (login, password reset), return the same response for "wrong password" and "unknown user" so the code cannot enumerate accounts.
- A 200 is not "safe". Attacks succeed with 200s all the time; the body matters as much as the code. Conversely a 403 does not mean the resource is truly protected — test, don't assume.
- Never redirect to an unvalidated target. Allow-list redirect destinations; a user-controlled 3xx target is an open redirect and a phishing/OAuth-theft vector.