6.5 Authentication, Session & Access-Control Flaws
Key Takeaways
- Broken authentication includes weak/credential-stuffing-prone logins, missing multi-factor authentication, and exposed credentials; the defense stack is strong password policy, MFA, lockout/rate limiting, and salted slow-hash credential storage.
- Session fixation forces a known session identifier onto a victim before login; the fix is to regenerate the session ID at every privilege change, especially at authentication.
- Insecure Direct Object Reference (IDOR) is a broken access control flaw where the application trusts a client-supplied object identifier without verifying the user is authorized for that object.
- JSON Web Token (JWT) flaws include accepting the 'none' algorithm, weak signing keys, and trusting unverified claims; tokens must be signed with a strong server-held key and fully validated server-side.
- Access control must be enforced server-side on every request with deny-by-default; client-side checks, hidden fields, and disabled UI buttons are not security controls.
Broken Authentication
Broken authentication (OWASP A07:2025, Authentication Failures) covers any weakness that lets an attacker assume another user's identity. Common conditions: permitting weak or breached passwords, no protection against credential stuffing (replaying leaked username/password pairs at scale), brute-force/password-spraying exposure, missing multi-factor authentication (MFA), predictable password-reset flows, exposed session identifiers in URLs, and storing credentials reversibly. Attackers test these with tools such as Hydra (online login brute-forcing) and Burp Intruder (automated request fuzzing).
Defenses: enforce a strong password policy and screen against known-breached password lists; require MFA, especially for sensitive or administrative roles; apply account lockout or progressive rate limiting against guessing and stuffing; store credentials only as salted, slow one-way hashes (e.g., bcrypt/Argon2-class functions); and standardize secure, non-enumerable password-reset flows.
Session Management Flaws
After login, the session identifier is the user's identity to the server, so its handling is security-critical.
- Session fixation — the attacker sets or obtains a session identifier before the victim authenticates, then gets the victim to log in under that known identifier; afterward the attacker reuses it as the now-authenticated user. Fix: always regenerate the session identifier at every privilege boundary, especially immediately after successful authentication, so any pre-login identifier becomes useless.
- Session hijacking — the attacker steals an active session token (via XSS, sniffing, or interception) and replays it. Fix: HTTPS everywhere,
HttpOnly/Secureflags, and binding/rotation. - Weak session identifiers — predictable or short tokens can be guessed or enumerated. Fix: long, cryptographically random identifiers.
- Poor lifecycle — no idle/absolute timeout, no invalidation on logout. Fix: server-side timeouts and explicit server-side invalidation on logout and password change.
| Session flaw | Core idea | Direct fix |
|---|---|---|
| Session fixation | Victim logs in under an attacker-known ID | Regenerate session ID after login |
| Session hijacking | Attacker steals/replays a live token | TLS + HttpOnly/Secure cookies |
| Predictable token | ID can be guessed | Long cryptographically random ID |
| No timeout/invalidation | Stale sessions stay valid | Idle/absolute timeout, logout invalidation |
Insecure Direct Object Reference (IDOR)
Insecure Direct Object Reference (IDOR) is a broken access control flaw (OWASP A01). The application exposes a reference to an internal object (an account number, record ID, filename) and acts on it using only the client-supplied value, without checking that the current user is authorized for that object. Changing the identifier to another user's value returns or modifies their data. IDOR is an authorization failure, not an authentication failure — the attacker is logged in as themselves; the system simply fails to check ownership.
Fix: perform an explicit server-side authorization check that the authenticated user owns or may access the requested object on every request. Using unpredictable identifiers is helpful obfuscation but is not a substitute for the authorization check.
JSON Web Token (JWT) Issues
A JSON Web Token (JWT) is a signed, self-contained token carrying identity/claims. Common flaws CEH expects you to recognize:
alg: noneacceptance — a token presented with the algorithm set to "none" (no signature) is trusted, letting an attacker forge claims. Fix: reject unsigned tokens; pin the expected algorithm server-side.- Algorithm confusion (RS256 → HS256) — tricking the server into verifying an asymmetric token with the public key as an HMAC secret. Fix: pin and enforce the expected algorithm.
- Weak or leaked signing key — a guessable secret allows forging valid tokens. Fix: strong, secret, server-held keys; rotate on exposure.
- No claim validation / no revocation — trusting role or identity claims without verifying signature, issuer, audience, and expiry; long-lived tokens that cannot be revoked. Fix: verify the signature first, then validate claims; use short lifetimes plus a denylist or token versioning.
The Common Thread: Server-Side, Deny-by-Default
Every flaw above shares one remediation principle CEH rewards: security decisions must be made and enforced on the server, default to deny, and be re-checked on every request. Client-side validation, hidden form fields, disabled UI buttons, and obscure identifiers improve usability or raise the bar slightly, but they are not access controls — an attacker speaks directly to the server with a proxy like Burp Suite and never sees the UI.
Access Control Models and Common Failures
CEH expects you to recognize how authorization is supposed to work and how it breaks:
- Vertical privilege escalation — a lower-privilege user gains higher-privilege (e.g., admin) capabilities, typically because a function-level check is missing.
- Horizontal privilege escalation — a user accesses another user's data at the same privilege level; IDOR is the classic example.
- Forced browsing — guessing or reaching unlinked URLs/endpoints that lack their own authorization check.
- Metadata/parameter tampering — changing a hidden field, cookie, or JWT claim (e.g.,
role=usertorole=admin) that the server trusts without revalidation.
| Failure | Example | Correct control |
|---|---|---|
| Missing function-level check | Standard user reaches /admin endpoint | Server-side role check per endpoint |
| Missing object-level check (IDOR) | Changing accountId reads another user | Server-side ownership check per object |
| Trusting client-side role | Tampered cookie/JWT claim grants admin | Re-derive privileges from a trusted server session |
| Forced browsing | Direct URL to an unlinked page | Deny-by-default on every route |
Enforcing Authorization Correctly
The model CEH rewards is deny-by-default, server-side, on every request. Centralize authorization so each request is checked against the authenticated identity and the specific resource and action requested; never rely on the absence of a UI link, a hidden field, or a disabled button. Pair this with the principle of least privilege (give each account, service, and token only the rights it needs) and strong logging so that authorization failures are detected. These same principles carry directly into API security in the next section, where Broken Object Level Authorization is the number-one risk.
A logged-in user changes the value of an accountId parameter in a request URL from their own number to a different one and receives another customer's statement. No login bypass occurred. Which flaw is this, and what is the correct fix?
An application accepts a JSON Web Token (JWT) whose header specifies the algorithm as 'none' and therefore carries no signature, and it trusts the claims inside. What is the primary remediation?
Which control most directly prevents session fixation?
A standard user tampers with a JWT claim, changing role from user to admin, and the server grants administrative access. What is the underlying mistake, and the correct fix?