OWASP Top 10, Explained for Developers Who Aren't Security Specialists

A plain-language walkthrough of the OWASP Top 10 web application security risks, with concrete examples and fixes for each.

DevFieldGuideJuly 17, 2026 (updated July 22, 2026)7 min read
Share:

Most developers have heard of the OWASP Top 10 but couldn't name more than two or three items on it. Here's what actually matters, in plain language.

1. Broken Access Control

Users acting outside their intended permissions — like editing another user's data by changing an ID in a URL.

GET /api/orders/1234 ← your order GET /api/orders/1235 ← someone else's order, if the server doesn't check ownership

Fix: Always verify the requesting user owns or has permission for the resource, server-side, on every request.

2. Cryptographic Failures

Sensitive data (passwords, tokens, PII) stored or transmitted without proper encryption.

Fix: Use HTTPS everywhere, hash passwords with bcrypt/argon2 (never plain hashes like MD5), and encrypt sensitive data at rest.

3. Injection

Untrusted input executed as code — SQL injection is the classic example.

js
// Vulnerable
db.query(`SELECT * FROM users WHERE email = '${input}'`);
 
// Safe — parameterized query
db.query("SELECT * FROM users WHERE email = ?", [input]);

Fix: Always use parameterized queries or an ORM. Never string-concatenate user input into a query.

4. Insecure Design

Security flaws baked into the architecture itself, not fixable by patching code — e.g., a password reset flow with no rate limiting.

Fix: Threat-model sensitive flows during design, not after an incident.

5. Security Misconfiguration

Default credentials, verbose error messages leaking stack traces, unnecessary services exposed.

Fix: Disable debug mode in production, remove default accounts, and minimize the attack surface.

6. Vulnerable and Outdated Components

Using dependencies with known CVEs.

Fix: Run npm audit / pip-audit in CI, and keep dependencies patched on a schedule, not just reactively.

7. Identification and Authentication Failures

Weak session management, predictable tokens, no multi-factor authentication.

Fix: Use established auth libraries rather than rolling your own, enforce MFA for sensitive accounts, and rotate session tokens on privilege changes.

8. Software and Data Integrity Failures

Trusting unsigned updates or CI/CD pipelines without integrity checks — the root cause of many supply-chain attacks.

Fix: Verify package signatures, pin dependency versions, and restrict who can publish to your package registry.

9. Security Logging and Monitoring Failures

Breaches that go undetected for months because nothing was logged or alerted on.

Fix: Log authentication events and access-control failures, and alert on anomalies — don't just log everything and never look at it.

10. Server-Side Request Forgery (SSRF)

Tricking a server into making requests to internal resources on the attacker's behalf.

POST /fetch-preview { "url": "http://169.254.169.254/latest/meta-data/" }

Fix: Validate and allowlist outbound request destinations; never let user input directly control a server-side fetch target.

#RiskRoot cause
1Broken Access ControlMissing server-side ownership checks
2Cryptographic FailuresSensitive data not properly encrypted
3InjectionUntrusted input executed as code
4Insecure DesignFlaws in the architecture itself
5Security MisconfigurationDefault credentials, verbose errors
6Vulnerable ComponentsDependencies with known CVEs
7Auth FailuresWeak sessions, no MFA
8Integrity FailuresUnsigned updates, unverified CI/CD
9Logging FailuresBreaches going undetected
10SSRFServer tricked into internal requests

The pattern across all ten

Nearly every item traces back to one root cause: trusting input or configuration that an attacker can influence. Validate at every boundary, and you'll have already mitigated most of this list.

Broken Access Control and weak authentication are exactly what two-factor authentication is designed to raise the cost of exploiting — worth pairing with the access-control fixes above rather than treating either as sufficient alone.

A concrete SSRF walkthrough, since it's the least intuitive item

SSRF (item 10) is the one developers most often struggle to picture concretely, so it's worth one more example. Imagine a feature that generates a link preview by fetching whatever URL a user submits:

js
// Vulnerable
app.post("/preview", async (req, res) => {
  const response = await fetch(req.body.url);
  res.json({ html: await response.text() });
});

This looks harmless — it's just fetching a URL to show a preview. But nothing stops a user from submitting an internal address instead of a real webpage:

POST /preview { "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }

On many cloud providers, that address is the instance metadata service — internal-only, unreachable from the public internet directly, but reachable from inside the server making the fetch. The server, trusted to make internal-network requests, has just been tricked into fetching (and potentially returning to the attacker) cloud credentials it should never expose. The fix is the same principle as injection generally: validate what the server is allowed to fetch (an allowlist of external domains, blocking internal/private IP ranges explicitly) rather than trusting user input to specify an arbitrary destination.

Where to start if you can only fix one thing this week

Given limited time, Broken Access Control and Injection are worth prioritizing first — they're both consistently among the most exploited categories in real-world breach data, and both have a concrete, mechanical fix (server-side ownership checks; parameterized queries) rather than requiring a broader process change. Cryptographic Failures (HTTPS everywhere, proper password hashing) is the other quick, high-leverage check, since a misconfiguration there is often a single settings change away from being fixed entirely.

This list isn't static — check the revision date

The specific ordering and even category boundaries shift between OWASP Top 10 revisions as real-world vulnerability data changes (Insecure Design, for instance, is a relatively recent addition reflecting a shift toward catching architectural flaws earlier). Treat the ten items above as the current shape of the list, worth periodically re-checking against OWASP's own published version rather than treated as permanently fixed — the underlying principle (validate everything an attacker can influence) is durable even as the specific list evolves.

Common mistakes

Common mistakes
  • Treating client-side validation as a security control. Anything enforced only in the browser (a disabled button, a JS length check) can be bypassed entirely by calling the API directly — client-side validation is a UX nicety, server-side validation is the actual control.
  • Rolling a custom authentication or session system instead of using an established library. Auth is deceptively easy to get mostly right and genuinely hard to get entirely right — the failure modes (session fixation, timing attacks on comparisons) are subtle and well-studied in existing libraries for a reason.
  • Assuming an ORM makes SQL injection impossible by default. Most ORMs are safe when used normally, but nearly all of them offer an escape hatch for raw queries — string-concatenating user input into that raw-query path reintroduces the exact vulnerability the ORM was protecting against.
  • Logging sensitive data (passwords, full card numbers, session tokens) "just in case it's useful for debugging." This turns your own logs into a target — log identifiers and context, never the secret itself.
Advertisement

Frequently Asked Questions

Advertisement
DevFieldGuide
DevFieldGuide

Editorial Team

Practical tutorials and developer tools, written and maintained by the DevFieldGuide team.

Enjoyed this article?

Get the next one straight to your inbox, along with the best of what we publish each week.

Related Articles

More in Cybersecurity

View all