~/learn / web-vulnerabilities
Web Vulnerabilities
The major classes of web application vulnerability, the handful of root causes they all reduce to, how to recognize each in code, how to fix it at the root, and how to practice legally, mapped to the OWASP Top 10.
The list of web vulnerability names looks endless and arbitrary when you first meet it. It is not. Almost every one reduces to a small number of root causes, and once you hold those in your head, a new vulnerability name stops being trivia to memorize and becomes a variation you can reason about from first principles. A good security engineer rarely recalls a checklist. They recognize a shape.
The four root causes
- Data treated as code. Untrusted input reaches an interpreter (SQL, HTML, a shell, a template engine, an XML or object parser) and changes what it does, because the interpreter cannot tell the developer’s instructions from the user’s data. This is the whole injection family: SQL injection, cross-site scripting, and command injection and its relatives. The structural fix is always the same shape: separate the code channel from the data channel so input can never cross over.
- Trust in the wrong party. The server trusts the browser to tell the truth, the browser trusts any site to send requests with your cookies attached, or a server trusts any URL it is handed. This is CSRF (the server over-trusting ambient cookies) and SSRF (the server over-trusting a user-supplied destination). The fix is to make trust explicit and verifiable: unguessable tokens, origin checks, allowlists.
- Missing checks. The code authenticates the user (who are you) but forgets to authorize the action (are you allowed to do this, to this specific object). This is broken access control, the single most common serious finding in real applications, covered in testing access control. The fix is an authorization check on every request and every object, enforced server-side.
- Broken assumptions. The code assumes steps happen in order, numbers are positive and bounded, or requests arrive one at a time. Reality violates all three. These are business logic and race condition bugs, invisible to scanners because the requests are all well-formed. The fix is to enforce the real invariants of the domain, atomically.
Notice that three of the four are not about clever payloads at all. They are about a program trusting something it should have verified. That is the defender’s secret: most security is disciplined distrust applied consistently.
OWASP Top 10 (2021) at a glance
The OWASP Top 10 is the industry’s shared vocabulary for these risks. Map each category back to a root cause above and it reads as the same four ideas, ranked by how often they cause real breaches.
| Rank | Category | Root cause | Where to read |
|---|---|---|---|
| A01 | Broken Access Control | Missing checks | Testing access control |
| A02 | Cryptographic Failures | Broken assumptions | Cryptography |
| A03 | Injection (including XSS) | Data as code | SQL injection, XSS |
| A04 | Insecure Design | Broken assumptions | Business logic |
| A05 | Security Misconfiguration | Missing checks | Header grader, CSP analyzer |
| A06 | Vulnerable Components | Missing checks | Exploit feed |
| A07 | Authentication Failures | Trust in the wrong party | Sessions and cookies |
| A08 | Software and Data Integrity Failures | Data as code | Injection and file flaws |
| A09 | Logging and Monitoring Failures | Missing checks | Cheatsheet: log analysis |
| A10 | Server-Side Request Forgery | Trust in the wrong party | SSRF |
A01 sitting at the top is not an accident. The least glamorous bug, a forgotten ownership check, breaches more applications than every injection combined, because it requires no payload and hides in plain sight.
How an attacker actually approaches an app
Understanding the order of operations makes the whole topic cohere. A tester, working only on systems in scope, roughly moves through: map the application and its state machine, enumerate every input and every object reference, probe each input for the data-as-code shapes, probe each object reference for missing authorization, then look for the domain-specific assumptions that no generic test would catch. The deeper the understanding of what the app is for, the more the last and most valuable category opens up.
How to practice safely and legally
Every page in this topic explains the mechanism with vulnerable and fixed code so you can recognize it by reading. To practice finding it, use applications built and licensed to be attacked, never a real site you do not own. Testing a live system without written permission is a crime in most jurisdictions even when the bug is trivial and your intent is benign.
- PortSwigger Web Security Academy: free, structured, lab-per-vulnerability, with solutions. The best starting point.
- OWASP Juice Shop and DVWA: full deliberately vulnerable apps you run locally.
- Hack The Box and TryHackMe: guided and unguided targets in a legal range.
The defender’s mindset
For every class, the durable fix is structural, never a filter bolted on afterward:
- Keep code and data separate with parameterized queries and contextual output encoding, so there is no payload to filter.
- Make the secure path the default path in your framework, so a developer has to go out of their way to be unsafe.
- Check authorization on the server for every request and every object, by default, failing closed.
- Layer defense in depth, a strict CSP, SameSite cookies, least-privilege database users, egress filtering, so that any single mistake is contained rather than catastrophic.
Read each topic in this section for the mechanism, the worked example, and the checklist. They are written to be understood, not memorized.
Go deeper
- SQL InjectionHow building SQL queries from strings lets input change the query, the parser-level reason it works, every form it takes, why escaping and blocklists fail, and why parameterized queries fix it completely.
- Cross-Site Scripting (XSS)How untrusted data becomes running JavaScript in another user's browser, the parsing contexts that decide whether it executes, the stored, reflected, and DOM variants, and why contextual encoding plus a strict CSP are the real fix.
- Cross-Site Request Forgery (CSRF)How a malicious site makes a logged-in browser send requests the user never intended, why ambient cookie authority is the root cause, what SameSite does and does not cover, and how tokens and origin checks close it.
- Server-Side Request Forgery (SSRF)How URL-fetching features get turned against internal networks and cloud metadata, the parser tricks that defeat blocklists, why DNS rebinding beats naive validation, and how allowlists, network egress control, and IMDSv2 contain it.
- Command Injection, Path Traversal, and Other FlawsThe rest of the injection family, OS command injection, path traversal, template injection, XXE, insecure deserialization, and unsafe uploads, each with the parser-level root cause, a worked example, and the fix that removes the channel rather than filtering it.
- Business Logic and Race ConditionsVulnerabilities that come from flawed assumptions rather than malformed input, including workflow bypasses, numeric and quantity abuse, and the concurrency mechanics behind race conditions, plus how to design them out with atomic operations and idempotency.