Skip to content
Tech Interview Prep home
Technical interview guide

Common Web Vulnerabilities (OWASP Top 10)

The most common web application security risks, and the concrete pattern behind each one.

Read
30 min
Practice MCQs
25
Interview QA
25
Edition
v3
Editorial status
Reviewed

Scope: OWASP Top 10:2025 and OWASP Cheat Sheet Series guidance accessed 2026-08-31..

Overview

Curated: · Written: · Reviewed:

OWASP Top 10:2025 as an engineering risk model

The OWASP Top 10 is an awareness document, not a complete security standard, certification, test plan, or promise that ten checks make an application secure. The 2025 edition groups hundreds of weaknesses into ten broad risk categories using contributed application data and practitioner survey input. Teams should map the categories to their own assets, actors, trust boundaries, business impact, technology, exposure, and abuse cases, then use a fuller verification standard and threat model for coverage.

In an interview, this topic shows up two ways: as a screening question ("walk me through the Top 10" — the interviewer is checking you can name categories and, more importantly, say what each one actually is) and as a design-review probe ("you're building a multi-tenant invoicing API — what are your top risks?"). The weak answer in both cases is reciting ten labels with a one-line definition each. The strong answer picks two or three categories relevant to the system described, names the concrete failure mode, and gives the structural fix. Expect follow-ups like "what's the difference between authentication and authorization failures," "why did XSS move into injection," and "your scanner is clean — what does that prove?" — all covered below.

The 2025 categories

  1. A01 Broken Access Control includes missing object, function, field, tenant, workflow, and server-side request restrictions. The server derives identity and ownership from trusted state, denies by default, and authorizes every resource/action. In 2025, SSRF is consolidated here: outbound fetchers need strict destination and scheme controls, DNS/IP validation, redirect handling, egress restrictions, time/size limits, and protection for metadata and internal services.
  2. A02 Security Misconfiguration includes unsafe defaults, unnecessary features, verbose errors, inconsistent environments, missing hardening, and permissive cloud, header, or network policy. Configuration is versioned, reviewed, tested, inventoried, and drift-detected—not a one-time deployment checklist.
  3. A03 Software Supply Chain Failures expands beyond known-vulnerable components to dependency selection, source and registry trust, build systems, CI identities, artifacts, signing/provenance, distribution, and emergency update/revocation. An SBOM improves inventory but neither proves safety nor prevents a compromised build.
  4. A04 Cryptographic Failures covers failure to identify protected data, inappropriate algorithms/protocols, weak randomness, key lifecycle mistakes, cleartext exposure, and incorrect password storage. Prefer established libraries and protocols, authenticated encryption where applicable, password hashing rather than reversible encryption, separated key management, rotation, recovery, and crypto-agility.
  5. A05 Injection occurs when untrusted data changes the syntax or meaning of a command, query, template, document, log, or rendered page. Keep data separate from instructions with parameterized APIs, safe structured builders, contextual output encoding, and narrowly scoped interpreters. Allow-list validation is useful but is not a universal substitute for safe APIs.
  6. A06 Insecure Design is missing or ineffective security requirements and controls at the architecture/business-logic level. Threat modeling, abuse cases, secure design patterns, trust-boundary review, resource limits, invariant/state-machine design, and misuse testing must precede and accompany implementation. A perfect implementation cannot add a control the design omitted.
  7. A07 Authentication Failures includes weak enrollment, authenticator, federation, recovery, session, and anti-automation lifecycles. Use established identity protocols, phishing-resistant authenticators where risk warrants, enumeration-aware responses, session rotation and expiry, rate limits, secure recovery, and reauthentication for sensitive changes. Authentication still does not replace authorization.
  8. A08 Software or Data Integrity Failures concerns trusting software, updates, serialized data, pipelines, or critical data without adequate integrity and provenance verification. Verify artifacts before execution, restrict signing and deployment identities, protect metadata, make rollback safe, and avoid unsafe deserialization. A signature proves control of a key, not that signed content is benign.
  9. A09 Security Logging and Alerting Failures covers missing, unusable, unprotected, or unmonitored security telemetry. Log normalized outcomes and reason codes, actor/tenant/action/resource and correlation context without credentials or tokens; centralize, protect integrity, retain by purpose, detect meaningful conditions, route alerts to owners, and rehearse response. Logs without actionable alerting and response do not contain an incident.
  10. A10 Mishandling of Exceptional Conditions is new in 2025 and includes failing open, missing-parameter handling, unsafe error paths, resource cleanup failures, partial commits, and sensitive error disclosure. Define secure failure semantics, bounded retries/timeouts, atomicity or compensation, resource limits, generic external errors with detailed protected diagnostics, and tests for dependency failure, malformed state, cancellation, concurrency, and rollback.

Where these came from: the 2021 list as attack patterns

The 2025 categories are regroupings of the 2021 list, which was organized closer to attack patterns. Knowing the 2021 set helps because interviewers, scanners, and pen-test reports still use its vocabulary. The 2021 list: A01 Broken Access Control (IDOR, missing function-level checks, CORS misconfiguration), A02 Cryptographic Failures, A03 Injection (with XSS folded in), A04 Insecure Design, A05 Security Misconfiguration, A06 Vulnerable and Outdated Components, A07 Identification and Authentication Failures, A08 Software and Data Integrity Failures, A09 Security Logging and Monitoring Failures, A10 SSRF.

The 2025 reshuffle: SSRF moved into A01; vulnerable components widened into A03 supply chain; misconfiguration and cryptography swapped to A02/A04; injection moved to A05; logging became "logging and alerting"; A10 became the new exceptional-conditions category. If an interviewer asks about SSRF or XSS, they are asking about attack patterns that now live inside broader 2025 categories — answer with the pattern, then name where it sits now.

The boundary pairs interviewers use to separate candidates

These pairs are where "I've heard of the Top 10" ends and understanding begins. Each pair is a likely follow-up question.

  • XSS vs CSRF. XSS is attacker-controlled script running in the victim's browser (untrusted data reaching a browser interpreter). CSRF is the attacker's request riding the victim's session — no script needed, the browser attaches credentials automatically. XSS defeats token-based CSRF defenses because the script can read the token; CSRF can exist with zero XSS. Different fixes: contextual output encoding plus CSP for XSS; synchronizer tokens and SameSite cookies for CSRF.
  • Injection vs Broken Access Control. Injection is untrusted data changing what a parser executes — the attacker exploits the interpreter. Broken access control is a legitimate user reaching a resource they shouldn't — the code runs exactly as written and the authorization decision is missing. No amount of encoding fixes a missing ownership check; no ownership check fixes a concatenated SQL string.
  • IDOR vs missing function-level authorization. IDOR is object-level: the request references another user's object (GET /invoices/4419) and the handler never checks ownership. Function-level is: the endpoint itself is admin-only (POST /admin/refund) and the check lives only in the UI that hides the button. The test for the first is "request another tenant's object"; for the second, "call the admin route with a user token."
  • SSRF vs generic misconfiguration. A permissive CORS header is a misconfiguration — a static setting that's wrong. SSRF is the application itself making attacker-influenced outbound requests; the fix is destination allowlists, scheme restrictions, and blocking link-local/metadata addresses, not a config toggle.
  • A07 vs A01 — who you are vs what you may do. Authentication establishes identity; authorization decides what that identity may touch. Systems fail when teams treat a valid token as permission. Every "authenticated user could read any record" bug is this confusion.
  • A04 vs A05 — flawed design vs flawed deployment. Insecure design means no control could have worked: the design never required an ownership check, so a correct implementation is still vulnerable. Misconfiguration means the design was right and the deployed state is wrong — debug endpoints exposed, default credentials, permissive bucket policy. The remediation paths differ: redesign vs config governance.

Canonical mitigations, and why each is the one

For each pattern there is a fix interviewers expect you to name without hesitation, plus a reason it beats the alternatives.

  • Injection → parameterized queries and allow-lists. Parameterization sends data as data: the driver transmits the value separately from the statement, so no input can change the query's structure. Escaping and filtering are secondary because each interpreter has its own grammar and each hand-rolled escape is a chance to miss a context. Allow-list validation narrows the input space but can't cover free-text fields, which is why it complements rather than replaces safe APIs.
  • XSS → contextual output encoding plus CSP. Encoding must match the sink: HTML-escaping inside element content does nothing for a javascript: URL or an attribute context. CSP is the backstop that limits what survives an encoding mistake by restricting script sources.
  • CSRF → synchronizer tokens and SameSite cookies. The token proves the request came from a page the site rendered; SameSite stops the browser attaching the session cookie to cross-site requests in the first place. Both are needed because SameSite has carve-outs and older browsers ignore it.
  • Broken access control → deny-by-default, server-side checks in one layer. The check must run on the server (client-side hiding is not a control), on every request, in a layer an endpoint cannot bypass — middleware or a repository gate, not per-handler discipline. Deny-by-default means a missing check fails closed.
  • Cryptographic failures → secret management and TLS posture. Secrets in a managed vault with scoped access and rotation, not in source or environment files committed to repos; TLS enforced with current protocol versions and sane cipher configuration, verified by scanning rather than assumed.
  • Vulnerable components → pinning, SCA, and signing. Pin dependency versions, run software-composition analysis in CI against a vulnerability database, and verify artifact signatures/provenance so the thing you deploy is the thing you built.
  • SSRF → IMDSv2 and egress allowlists. On AWS, IMDSv2 requires a session token an SSRF response can't easily yield, killing the classic credential theft; egress allowlists at the network layer mean even a fully-controlled fetcher can't reach internal services. Both are structural: they hold even when the application code is already vulnerable.

Why XSS moved into injection, and what that implies

In 2021 OWASP folded XSS into A03 Injection. The reasoning: injection is one family — untrusted data crossing a trust boundary into an interpreter that gives it meaning. SQL injection puts data into the SQL interpreter; command injection into a shell; XSS into the browser's HTML/JS interpreter. The implication for interviews: when asked "how do you prevent injection," the strong answer is the family-level principle — keep data and instructions separate, using the mechanism the target interpreter provides (bind parameters for SQL, contextual encoding for HTML) — rather than a list of per-vector tricks. It also explains why "sanitize all input" is the weak answer: sanitization is one tool in the triad below, not the family-level fix.

The input-handling triad: validation, encoding, sanitization

These three get used interchangeably by weak candidates. They are not interchangeable.

  • Validation checks input against an expected shape at the boundary — type, length, format, membership in an allow-list — and rejects what doesn't fit. It shrinks the attack surface before data enters the system. It cannot make dangerous data safe; it can only refuse it. Free-text fields can't be fully validated, which is why validation alone never suffices.
  • Encoding/escaping transforms data on the way out, for one specific output context: HTML-escaping for element content, URL-encoding for a query parameter, parameter binding for SQL. The same value needs different encoding per sink. This is the primary defense against injection and XSS because it guarantees the interpreter sees data, not structure, regardless of what the input contained.
  • Sanitization rewrites input to remove dangerous constructs — stripping tags from rich text, for example. It's the hardest to get right: it must parse the input the same way the downstream consumer will, and every sanitizer/parser mismatch is a bypass. Use it only where you must accept markup, and use a maintained library, never regex.

The rule to state in an interview: validate at entry to fail fast and narrow the surface, encode at every exit for the context of that exit, sanitize only when the format genuinely requires accepting rich input. Applying encoding where validation belongs (or vice versa) is a classic finding.

Applying the list

Start from a data-flow and trust-boundary model. For each endpoint, job, event, administrator path, and dependency, enumerate assets, attackers, preconditions, abuse cases, controls, evidence, owner, and residual risk. Write security invariants such as "a tenant can never observe another tenant's object" or "unsigned release artifacts never execute," then test them at unit, integration, system, and operational layers. Combine code review, SAST, DAST, dependency and secret scanning, IaC/container/cloud checks, fuzzing, penetration testing, and production detection; each sees different failure modes and each has false positives and blind spots.

Prioritize using local likelihood, exploitability, blast radius, data sensitivity, exposure, control strength, and business impact—not category rank alone. Fix root causes and shared control paths, add regression tests, inventory affected variants, deploy with rollback, and verify in production. Track exceptions with owner, rationale, compensating controls, expiry, and review. The goal is a repeatable secure-development and incident-learning system, not memorization of ten labels.

The list is a prioritised awareness document derived from observed data, not a checklist and not a standard to be certified against. Two consequences follow. The first is that category rank reflects prevalence across the surveyed population rather than risk in your system: an application with no server-side request forgery surface gains nothing from work on that category however highly it ranks, while a category near the bottom may be the one that matters most given what your system holds. The second is that clearing all ten says nothing about the vulnerabilities that were never in scope — business-logic flaws in particular, which are the most common cause of real loss and which no generic category names because they are specific to what the application is for.

Most categories are best addressed structurally rather than instance by instance. Injection is not fixed by escaping each query but by making parameterisation the only available path, so that a string-concatenated query cannot be written without deliberate effort. Broken access control is not fixed by auditing endpoints but by enforcing the check in a layer every request passes through and failing closed when the object's owner cannot be determined, since the recurring failure is an endpoint that forgot rather than one that got it wrong. Ask of each finding what change would make the whole class impossible, and treat the individual fix as the interim measure.

Verification has to reach past what the scanners see. Automated scanning finds patterns and misses anything requiring an understanding of intent, which is exactly where access-control and business-logic flaws live, so a clean scan is a statement about the scanner's rules rather than about the application. Complement it with targeted review of the authorisation paths, tests that assert a user cannot reach another user's object, and dependency analysis that considers whether a vulnerable path is reachable rather than merely present.

Worked example: a clean scan still leaked invoice 4419

GET /invoices/4419. Token is tenant B. Invoice belongs to tenant A. SAST/DAST reports zero findings.

controlHTTPtenant A data
role=user in JWT, scanner green200leaked
object-owner check in one fail-closed layer404hidden

A01 is the forgotten endpoint, not the scanner rule. The test is another tenant's object. This is the example to reach for when an interviewer asks what a clean scan proves: nothing about authorization, because the scanner doesn't know which tenant should see which invoice — only your invariant test does.