
OWASP Top 10:2025 — Part II + XSS & CSRF
A06 through A10 of the 2025 list — insecure design, authentication failures, software/data integrity, logging & alerting, and the new A10:2025 (Mishandling of Exceptional Conditions). Plus a deep dive on XSS and CSRF, the two web bugs every engineer should be able to draw on a whiteboard.
What you will learn
The first half of the 2025 list is about what you wrote and what you shipped with. The second half is about what happens around it: the design choices you didn't make, the auth corners you cut, the integrity checks you skipped, the telemetry you forgot, and — new in 2025 — the exceptions you let escape. We close with the two web-specific bugs (XSS, CSRF) that don't have their own Top 10 slots but underpin huge swathes of A01, A05, and A07.
A06:2025 — Insecure Design
Down from #4 in 2021. The category covers bugs that are architecturally wrong — no amount of patching makes them safe; the design is the bug. A few canonical examples:
- Password reset that emails the password back in plaintext.
- Two-factor reset that requires only the original factor ("forgot your token? we'll text the same number").
- An API that accepts the price of a cart from the client and trusts it.
- Rate limiting bolted on per-IP when the abuse vector is per-account.
- Caching authenticated content on a shared CDN.
- Object-permission checks delegated to the front end.
The fix is upstream of code: threat modelling done early (Day 1 PM), secure design patterns (server-authoritative state, pre-built libraries for tricky flows, defence-in-depth), and abuse-case stories alongside user stories. OWASP recommends practicing it with the SAMM and Cornucopia card games — they sound silly; they work.
A07:2025 — Authentication Failures
Renamed from "Identification and Authentication Failures" to just Authentication Failures for clarity. Top patterns are the same — see Day 2 PM for the deep dive. The 2025 update emphasises:
- Brute-force / credential stuffing without rate limiting or breach-list checks.
- SMS-based MFA where SIM swap is in scope (NIST has effectively deprecated SMS for high-assurance use).
- Predictable session IDs, or rotating them at the wrong moment (post-login session fixation).
- Long-lived bearer tokens that survive logout.
- "Forgot password" emails with predictable or non-expiring tokens.
- WebAuthn / passkeys not supported, leaving phishing-resistant auth off the table for users who want it.
Show answer
A08:2025 — Software or Data Integrity Failures
The category covers two related ideas: code or data flowing into your system without integrity checks, and CI/CD pipelines treated as trusted backdoors. SolarWinds (2020) is still the canonical example — a build pipeline was compromised and a signed update shipped malware to 18,000 customers.
- Auto-update without signature verification.
- CDN-delivered scripts without
integrity="sha384-…"SRI tags. - Insecure deserialisation (Java
ObjectInputStream, RubyMarshal, Pythonpickle). - CI runners that mount workspace secrets and pull untrusted code from PRs.
- Webhook receivers that don't verify HMAC signatures (or use
==for constant-time comparison).
A09:2025 — Security Logging & Alerting Failures
Renamed from "Logging and Monitoring Failures" — the new title makes the point: logs without alerts are file storage. If you cannot answer "who did what, when, on which resource" within minutes, and have an alert on the things that matter, you have an A09 problem. The 2025 OWASP report still measures median time-to-detect a breach in weeks, almost always because the logs you needed weren't captured, weren't retained, or weren't searchable.
The minimum bar for any application:
- Authentication, authorization, and admin events to a central, append-only log.
- Sensitive operations logged with actor + target + result, never with secrets in the body.
- Logs shipped off-host (an attacker rooting a box must not delete the audit trail).
- Alerts on key signals: login spikes, privilege changes, mass-export, error-rate inversions.
- Retention long enough for incident response — often 90 days hot, 1 year cold.
- SIEM / detection rules tested against the same playbook you'd run during an incident.
A10:2025 — Mishandling of Exceptional Conditions NEW
Brand new in 2025. It absorbs the slot SSRF vacated and covers 24 CWEs around improper error management. OWASP's framing: "programs fail to prevent, detect, and respond to unusual and unpredictable situations, leading to crashes, unexpected behaviour, and sometimes vulnerabilities." In other words, unhandled errors become an attack surface.
The Four Anti-Patterns the Category Calls Out
- Catching too broadly and ignoring (
except Exception: pass,catch (Throwable t) {}) — corrupt state continues silently. CWE-755, CWE-390. - Failing open — when authorisation, signature verification, or rate limiting throws, allowing the request "to avoid breaking the user experience." CWE-636.
- Verbose error pages in production — stack traces with table names, file paths, secrets in env. CWE-209.
- Resource leaks under error — connections, locks, temporary files left dangling, leading to resource exhaustion DoS. CWE-404.
def verify_signature(payload, sig): try: return hmac.compare_digest( sign(payload), sig ) except Exception: return True # fail open!
def verify_signature(payload, sig): try: return hmac.compare_digest( sign(payload), sig ) except (TypeError, ValueError) as e: log.warning("sig verify error", exc_info=e) return False # fail closed
Prevention Strategy
- Catch close to the source with specific exception types — not bare
except. - Always fail closed on security-relevant operations (signature verify, authorisation lookup, decryption, rate limiting).
- Centralised exception handler that returns a generic 500 in production while logging the full stack with a correlation ID.
- Validate inputs at trust boundaries before they reach the parser that might throw.
- Use transactions / context managers so resources release even on error (Python
with, Java try-with-resources, Godefer). - Test the unhappy paths — chaos / fault-injection tests catch the patterns SAST cannot.
Bonus: XSS — Cross-Site Scripting
XSS is now folded into A05 (Injection) but deserves its own section because it remains the single most-found web bug in bug bounties. Three flavors:
- Payload in URL → echoed back unescaped
- Requires the victim to click a crafted link
?q=<script>…
- Payload saved (comment, profile bio)
- Triggers for every viewer
- Worst impact
And DOM-based — the dangerous sink is in client JS (innerHTML, document.write, eval). The fix in modern frameworks: don't disable React/Vue/Angular's auto-escaping. dangerouslySetInnerHTML earns its name.
The Three-Layer XSS Defence
- Output encoding appropriate to context — HTML body, attribute, JS string, URL, CSS. Frameworks usually do this for you; don't disable it.
- CSP — a strong
Content-Security-Policywith nonces or hashes blocks inline JS even if a payload lands. - HttpOnly cookies — at minimum, make session theft impossible from a successful XSS.
Bonus: CSRF — Cross-Site Request Forgery
The browser sends your cookies on every request to your domain — including requests issued by JavaScript on another site. CSRF abuses that ambient authority: a malicious page makes the victim's browser perform a state-changing action against your site while logged in.
The CSRF defence stack
- SameSite=Lax (or Strict) on session cookies — solves CSRF for top-level navigations in modern browsers.
- Anti-CSRF tokens — synchroniser-token or double-submit-cookie pattern, validated on every state-changing request.
- Custom-header check — for pure-API JSON endpoints, require an
X-Requested-WithorOriginmatch. Browsers refuse to add custom headers cross-site without a CORS preflight. - Re-authentication on truly destructive actions (delete account, change password, send wire).
- A06 Bad blueprints — Insecure Design
- A07 Weak login — Authentication Failures
- A08 Broken signatures — Software/Data Integrity
- A09 Blind logs — Logging & Alerting
- A10 Swallowed errors — Mishandling Exceptional Conditions
- A10:2025 — Mishandling of Exceptional Conditions (24 CWEs)owasp.org
- A06:2025 — Insecure Designowasp.org
- OWASP XSS Prevention Cheat Sheetowasp.org
- OWASP CSRF Prevention Cheat Sheetowasp.org
- Content Security Policy referencecontent-security-policy.com
- OWASP ASVS — Application Security Verification Standardowasp.org
- CWE-755: Improper Handling of Exceptional Conditionscwe.mitre.org
- CWE-636: Not Failing Securely ("Failing Open")cwe.mitre.org
Finished reading?