<authentication_jwt_guide>
<title>AUTHENTICATION AND JWT/OIDC</title>

<critical>JWT/OIDC failures often enable token forgery, token confusion, cross-service acceptance, and durable account takeover. Do not trust headers, claims, or token opacity without strict validation bound to issuer, audience, key, and context.</critical>

<scope>
- Web/mobile/API authentication using JWT (JWS/JWE) and OIDC/OAuth2
- Access vs ID tokens, refresh tokens, device/PKCE/Backchannel flows
- First-party and microservices verification, gateways, and JWKS distribution
</scope>

<methodology>
1. Inventory issuers and consumers: identity providers, API gateways, services, mobile/web clients.
2. Capture real tokens (access and ID) for multiple roles. Note header, claims, signature, and verification endpoints (/.well-known, /jwks.json).
3. Build a matrix: Token Type × Audience × Service; attempt cross-use (wrong audience/issuer/service) and observe acceptance.
4. Mutate headers (alg, kid, jku/x5u/jwk, typ/cty/crit), claims (iss/aud/azp/sub/nbf/iat/exp/scope/nonce), and signatures; verify what is actually enforced.
</methodology>

<discovery_techniques>
<endpoints>
- Well-known: /.well-known/openid-configuration, /oauth2/.well-known/openid-configuration
- Keys: /jwks.json, rotating key endpoints, tenant-specific JWKS
- Auth: /authorize, /token, /introspect, /revoke, /logout, device code endpoints
- App: /login, /callback, /refresh, /me, /session, /impersonate
</endpoints>

<token_features>
- Headers: {% raw %}{"alg":"RS256","kid":"...","typ":"JWT","jku":"...","x5u":"...","jwk":{...}}{% endraw %}
- Claims: {% raw %}{"iss":"...","aud":"...","azp":"...","sub":"user","scope":"...","exp":...,"nbf":...,"iat":...}{% endraw %}
- Formats: JWS (signed), JWE (encrypted). Note unencoded payload option ("b64":false) and critical headers ("crit").
</token_features>
</discovery_techniques>

<exploitation_techniques>
<signature_verification>
- RS256→HS256 confusion: change alg to HS256 and use the RSA public key as HMAC secret if algorithm is not pinned
- "none" algorithm acceptance: set {% raw %}"alg":"none"{% endraw %} and drop the signature if libraries accept it
- ECDSA malleability/misuse: weak verification settings accepting non-canonical signatures
</signature_verification>

<header_manipulation>
- kid injection: path traversal {% raw %}../../../../keys/prod.key{% endraw %}, SQL/command/template injection in key lookup, or pointing to world-readable files
- jku/x5u abuse: host attacker-controlled JWKS/X509 chain; if not pinned/whitelisted, server fetches and trusts attacker keys
- jwk header injection: embed attacker JWK in header; some libraries prefer inline JWK over server-configured keys
- SSRF via remote key fetch: exploit JWKS URL fetching to reach internal hosts
</header_manipulation>

<key_and_cache_issues>
- JWKS caching TTL and key rollover: accept obsolete keys; race rotation windows; missing kid pinning → accept any matching kty/alg
- Mixed environments: same secrets across dev/stage/prod; key reuse across tenants or services
- Fallbacks: verification succeeds when kid not found by trying all keys or no keys (implementation bugs)
</key_and_cache_issues>

<claims_validation_gaps>
- iss/aud/azp not enforced: cross-service token reuse; accept tokens from any issuer or wrong audience
- scope/roles fully trusted from token: server does not re-derive authorization; privilege inflation via claim edits when signature checks are weak
- exp/nbf/iat not enforced or large clock skew tolerance; accept long-expired or not-yet-valid tokens
- typ/cty not enforced: accept ID token where access token required (token confusion)
</claims_validation_gaps>

<token_confusion_and_oidc>
- Access vs ID token swap: use ID token against APIs when they only verify signature but not audience/typ
- OIDC mix-up: redirect_uri and client mix-ups causing tokens for Client A to be redeemed at Client B
- PKCE downgrades: missing S256 requirement; accept plain or absent code_verifier
- State/nonce weaknesses: predictable or missing → CSRF/logical interception of login\n- Device/Backchannel flows: codes and tokens accepted by unintended clients or services
</token_confusion_and_oidc>

<refresh_and_session>
- Refresh token rotation not enforced: reuse old refresh token indefinitely; no reuse detection
- Long-lived JWTs with no revocation: persistent access post-logout
- Session fixation: bind new tokens to attacker-controlled session identifiers or cookies
</refresh_and_session>

<transport_and_storage>
- Token in localStorage/sessionStorage: susceptible to XSS exfiltration; cookie vs header trade-offs with SameSite/CSRF
- Insecure CORS: wildcard origins with credentialed requests expose tokens and protected responses
- TLS and cookie flags: missing Secure/HttpOnly; lack of mTLS or DPoP/"cnf" binding permits replay from another device
</transport_and_storage>
</exploitation_techniques>

<advanced_techniques>
<microservices_and_gateways>
- Audience mismatch: internal services verify signature but ignore aud → accept tokens for other services
- Header trust: edge or gateway injects X-User-Id; backend trusts it over token claims
- Asynchronous consumers: workers process messages with bearer tokens but skip verification on replay
</microservices_and_gateways>

<jws_edge_cases>
- Unencoded payload (b64=false) with crit header: libraries mishandle verification paths
- Nested JWT (JWT-in-JWT) verification order errors; outer token accepted while inner claims ignored
</jws_edge_cases>

<special_contexts>
<mobile>
- Deep-link/redirect handling bugs leak codes/tokens; insecure WebView bridges exposing tokens
- Token storage in plaintext files/SQLite/Keychain/SharedPrefs; backup/adb accessible
</mobile>

<sso_federation>
- Misconfigured trust between multiple IdPs/SPs, mixed metadata, or stale keys lead to acceptance of foreign tokens
</sso_federation>
</special_contexts>

<chaining_attacks>
- XSS → token theft → replay across services with weak audience checks
- SSRF → fetch private JWKS → sign tokens accepted by internal services
- Host header poisoning → OIDC redirect_uri poisoning → code capture
- IDOR in sessions/impersonation endpoints → mint tokens for other users
</chaining_attacks>

<validation>
1. Show forged or cross-context token acceptance (wrong alg, wrong audience/issuer, or attacker-signed JWKS).
2. Demonstrate access token vs ID token confusion at an API.
3. Prove refresh token reuse without rotation detection or revocation.
4. Confirm header abuse (kid/jku/x5u/jwk) leading to key selection under attacker control.
5. Provide owner vs non-owner evidence with identical requests differing only in token context.
</validation>

<false_positives>
- Token rejected due to strict audience/issuer enforcement
- Key pinning with JWKS whitelist and TLS validation
- Short-lived tokens with rotation and revocation on logout
- ID token not accepted by APIs that require access tokens
</false_positives>

<impact>
- Account takeover and durable session persistence
- Privilege escalation via claim manipulation or cross-service acceptance
- Cross-tenant or cross-application data access
- Token minting by attacker-controlled keys or endpoints
</impact>

<pro_tips>
1. Pin verification to issuer and audience; log and diff claim sets across services.
2. Attempt RS256→HS256 and "none" first only if algorithm pinning is unclear; otherwise focus on header key control (kid/jku/x5u/jwk).
3. Test token reuse across all services; many backends only check signature, not audience/typ.
4. Exploit JWKS caching and rotation races; try retired keys and missing kid fallbacks.
5. Exercise OIDC flows with PKCE/state/nonce variants and mixed clients; look for mix-up.
6. Try DPoP/mTLS absence to replay tokens from different devices.
7. Treat refresh as its own surface: rotation, reuse detection, and audience scoping.
8. Validate every acceptance path: gateway, service, worker, WebSocket, and gRPC.
9. Favor minimal PoCs that clearly show cross-context acceptance and durable access.
10. When in doubt, assume verification differs per stack (mobile vs web vs gateway) and test each.
</pro_tips>

<remember>Verification must bind the token to the correct issuer, audience, key, and client context on every acceptance path. Any missing binding enables forgery or confusion.</remember>
</authentication_jwt_guide>
