Web Security's threat-modeling lesson covered finding vulnerabilities through deliberate human review. Real teams pair that with automated tooling too — and the three major categories of security-testing tool each catch a genuinely different, non-overlapping slice of what's actually wrong with a codebase.
4 min read
Static Application Security Testing analyzes source code (or compiled bytecode) without executing it — pattern-matching against known-dangerous constructs (string-concatenated SQL, eval() on user input, a hardcoded secret literal) and, in more sophisticated tools, actually tracing whether untrusted input can reach a dangerous function (a taint analysis, following a variable from where it enters the program to everywhere it's subsequently used).
SAST finds: SAST misses:
- SQL built via string concat - Business logic flaws (lesson 2) —
- A hardcoded API key in source the code is syntactically fine,
- eval() called on a variable the WORKFLOW logic is wrong
traceable back to user input
SAST runs early — directly in CI, on every pull request, often in seconds — which is exactly its real advantage: catching a dangerous pattern before code ever merges, not after it's running in production. Its real limitation is equally direct: it reasons about code structure, so it has no way to catch a vulnerability that only exists in how a feature's business rules are (mis)implemented, since nothing about that code is syntactically wrong.
Dynamic Application Security Testing runs against a live, deployed (usually in a staging environment) application exactly the way an actual attacker would — sending real HTTP requests, including deliberately malicious payloads (the SQL-injection and XSS payloads Web Security's own lessons described), and observing the actual responses for signs the exploit worked.
DAST's real advantage is that it finds what's actually reachable and exploitable in a genuinely running system — including vulnerabilities introduced by configuration, not just code (a missing security header, a misconfigured CORS policy) that SAST, reading source code alone, would never see. Its real limitation: it runs late, against a deployed build, and can only test what it can actually reach through the application's exposed surface — it has no visibility into application logic it can't trigger through an HTTP request.
Fuzzing generates massive numbers of randomized, malformed, or edge-case inputs and feeds them to a program (a function, a file parser, an API endpoint), watching specifically for crashes, hangs, or memory-safety violations (lesson 4) — it isn't looking for a specific known vulnerability pattern the way SAST is; it's looking for any input that makes the program behave in a way its author never anticipated at all.
Fuzzer tries: "", "a" * 10000, "\x00\x01\x02...", malformed JSON,
deeply nested structures, unexpected encodings...
→ Looking for: a crash, an infinite loop, a memory-safety violation
Fuzzing is disproportionately valuable for exactly the memory-safety bug classes lesson 4 covered (a buffer overflow is, definitionally, triggered by some specific malformed input a fuzzer is well-suited to eventually stumble onto) and for any code that parses untrusted, structured input — file formats, network protocols, configuration files — where the space of possible malformed input is enormous and a human can't enumerate it by hand.
| Tool | Finds | Misses |
|---|---|---|
| SAST | Known-dangerous code patterns, early, in CI | Business logic, runtime config, anything requiring an actual running system |
| DAST | What's actually exploitable in a live, deployed system, including config | Logic it can't trigger externally; runs too late to block a merge |
| Fuzzing | Unanticipated crashes and memory-safety issues from malformed input | Anything that requires well-formed, "valid-looking" malicious input (most business logic and access-control bugs) |
None of the three overlaps meaningfully with the others' blind spots, and none of them catches business logic vulnerabilities (lesson 2) or BOLA (lesson 3) at all — those remain squarely a human threat-modeling and code-review problem, the exact gap Web Security's own lesson on that topic already named. Automated tooling and deliberate human review are complementary, not substitutes for each other.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What does SAST analyze, and when does it typically run?
2. What real class of vulnerability can DAST catch that SAST, reading source code alone, cannot?
3. Why is fuzzing particularly well-suited to finding memory-safety bugs?
Application Security & Secure Coding