Every specific vulnerability this curriculum has covered has its own specific fix. This lesson is about the layer above all of them — architectural decisions that determine how much damage ANY single vulnerability, including one nobody's thought of yet, can actually do once it's exploited.
3 min read
Defense in depth is the principle of layering independent security controls so that a single failure — one missed validation, one overlooked permission check, one zero-day in a dependency — doesn't translate directly into full compromise. Web Security's secrets-management lesson already applied a narrow version of this idea (scoping each service's database credential to only what it needs); this lesson is the same principle applied at the level of overall system architecture, not just one credential.
A system relying on exactly one control (a single perimeter firewall, one all-powerful database credential, input validation at exactly one entry point) turns that control's failure into total compromise. A system with several independent layers means an attacker who gets past the first one still has to get past the next, and the next — genuinely raising the cost and difficulty of a full compromise, not just the chance of catching the first attempt.
A traditional "hard perimeter, soft interior" network trusts anything already inside the network boundary — once an attacker compromises any internal service, nothing stops it from freely reaching every other internal system. Network segmentation restricts which services can actually talk to which others, regardless of being "inside" the same network, so compromising a low-value reporting service doesn't automatically grant a path to the payments database. Zero trust pushes this further: no request is trusted merely because of where it originates (inside vs. outside the network) — every request, internal or external, is authenticated and authorized on its own merits, the network boundary itself carrying no implicit trust at all.
# FAIL-OPEN — dangerous: an error in the check grants access by default
try:
if not check_permission(user, resource):
return "Forbidden", 403
except Exception:
pass # falls through to allowing the request if the check itself throws
# FAIL-CLOSED — safe: an error in the check denies access by default
try:
if not check_permission(user, resource):
return "Forbidden", 403
except Exception:
return "Forbidden", 403 # any failure in the check itself also deniesA security check that fails open — silently granting access if the check itself errors out — turns any bug, timeout, or unexpected exception in the permission logic itself into an automatic bypass of that exact permission check, often completely invisibly, since the application keeps working normally from a user's point of view. A check that fails closed treats any failure in the check itself as a denial — the safe default for anything security-relevant, even though it means a bug can occasionally deny access a legitimate user should have gotten (a real, acceptable availability cost, traded deliberately against the alternative of an invisible, silent security bypass).
Rather than asking only "how do we prevent this specific thing from happening," defense in depth asks a second, complementary question for every component: "if this specific thing happens anyway, how much can it actually reach." A compromised low-privilege worker service scoped to read one queue and write to one table has a small blast radius by design; a compromised service running with admin database credentials "just in case it needs them later" has a blast radius as large as the entire database, regardless of whether the specific vulnerability that got exploited had anything to do with most of that access at all.
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What does defense in depth assume about any single security control?
2. What's the difference between failing open and failing closed in a security check?
3. What does "blast-radius thinking" add to the usual question of preventing a specific vulnerability?
Application Security & Secure Coding