The Top 10 is a shortlist of patterns
The OWASP Top 10 is a community-maintained list of the most common categories of web vulnerability. It is not a checklist; it is a guidebook for what to expect. The categories get reshuffled every few years, but the underlying patterns barely change.
At a higher level, every web bug in the list is some variation of:
- Data from one trust zone is treated as code or as truth in another.
- The application forgets to enforce something on the server because the UI seems to enforce it.
- The application trusts the wrong thing: the user, the network, the framework defaults.
Injection (the classic: SQL injection)
Injection happens when user input is glued into a command or query without being treated as data. The textbook example is SQL:
query = "SELECT * FROM users WHERE email = '" + email + "'"
If email is alice@x.com, fine. If it's ' OR 1=1; --,
the database happily returns every user.
The fix is parameterized queries: the structure of the SQL is sent separately from the values, so user input can never become part of the command. This is a one-line change in every modern library, and it solves the entire class of problem.
"Sanitize input" is a trap
The correct framing isn't "clean the dangerous characters". It's "keep user data in the data slot, not the command slot." Parameterized queries, template engines that auto-escape, and prepared statements all do this for you.
Cross-Site Scripting (XSS)
XSS is injection's twin in the browser. The site echoes user-controlled data into the page without escaping it; that data turns out to be HTML or JavaScript; the script runs in another user's session.
From there an attacker can steal cookies, hijack actions, deface the page, or redirect. Three flavors:
- Reflected: the malicious string is in the URL.
- Stored: the string is saved (a comment, a profile field) and runs for every visitor.
- DOM-based: the bug lives in the client-side JavaScript, which builds DOM from URL/fragment data unsafely.
Defenses, in roughly the order they matter:
- Use a template system that escapes by default. Almost every modern framework does.
- Set a Content Security Policy that restricts where scripts may come from.
- Mark sensitive cookies
HttpOnlyso script can't read them. - Avoid
innerHTMLwith untrusted strings; prefertextContentor trusted-types APIs.
Cross-Site Request Forgery (CSRF)
CSRF exploits the fact that the browser automatically sends your cookies to the site they
belong to. A malicious page that submits a form to bank.example.com rides on
whatever session you already have there.
Defenses:
- SameSite cookies: the modern default.
Laxalready blocks most of this;Strictblocks more at a UX cost. - CSRF tokens: a per-form, per-session secret the server checks on submit.
- Origin / Referer checks on state-changing requests.
Broken access control
The most boring and most expensive bug class. The server enforces permissions in the UI (hides a button) but not in the API (the endpoint still works if you call it directly). Or, two users' URLs differ by an ID and there's no check that the caller owns that ID. This is called IDOR (Insecure Direct Object Reference).
The fix is conceptual, not technical: every server endpoint must check, on every call, "does the current identity have the right to do this to this resource?" No amount of frontend cleverness substitutes.
Server-Side Request Forgery (SSRF)
SSRF is when the server makes outbound requests to a URL the attacker controls. The
attacker uses the server as a proxy into places they couldn't reach themselves:
internal services, cloud metadata endpoints (169.254.169.254), or external
targets to which the server's IP is allow-listed.
Defenses include strict allow-lists of destinations, blocking link-local and private ranges, and never assuming the network is the boundary.
Frameworks did most of the work
Modern frameworks (Rails, Django, Express with sensible middleware, Next.js, Laravel) default to safe behavior for most of these. Most modern XSS, SQLi, and CSRF bugs are where developers stepped off the framework's defaults.