Thinking like an attacker — trust boundaries and attack surface
Nearly every vulnerability in this domain comes down to the same root cause: code trusted input that crossed a boundary it shouldn't have — learning to spot where those boundaries actually are is what makes every specific attack in this domain recognizable on sight.
4 min read
The one question that underlies almost every vulnerability in this domain
Every piece of data your code processes came from SOMEWHERE. The question
that matters: did it cross a TRUST BOUNDARY on the way in — did it
originate from something you don't fully control (a user's browser, a
third-party API, a file someone uploaded) — and if so, did your code
verify it before acting on it as if it were safe?
A trust boundary is any point where data moves from something you don't control into something you do — a form field a user typed into, a URL parameter, an HTTP header, a file upload, a webhook payload from a third-party service. Data on the far side of a trust boundary is, by default, untrusted — it could be anything, including something deliberately crafted to break your code's assumptions. Nearly every vulnerability covered later in this domain (SQL injection, XSS, path traversal, SSRF) is the same root cause wearing a different costume: untrusted input crossed a trust boundary, and the code on the other side treated it as if it had already been verified.
Attack surface: everywhere an attacker could actually try something
Every one of these is a real point of attack surface:
- Every form field and URL parameter
- Every HTTP header a request can set (not just the body)
- Every file upload endpoint
- Every webhook or third-party integration accepting inbound data
- Every API endpoint, including ones not linked from the UI at all
- Every dependency (a library) your code calls into
Attack surface is the complete set of points where an attacker could attempt to influence your application's behavior — and it's almost always larger than what a feature's own UI suggests, since an API endpoint, a webhook receiver, or a header can be reached directly, without ever going through the UI at all. A genuinely common, real mistake is reasoning about security only in terms of "what the UI lets a user type," while ignoring that an attacker can send arbitrary HTTP requests directly to any endpoint the server exposes, regardless of whether any legitimate UI path leads there.
Why "the user wouldn't do that" is not a security argument
# A REAL, common mistake: reasoning about security based on what the
# UI's own dropdown or form validation allows, rather than what the
# SERVER actually accepts from a raw HTTP request
# The browser's <select> only offers "admin" and "user" as options —
# but nothing stops an attacker from sending role=superadmin directly
# in a raw POST request, bypassing the dropdown entirelyClient-side validation (a dropdown's fixed options, a form's required attribute, JavaScript checking input before submission) is genuinely useful for user experience — catching typos, guiding correct input — but provides zero actual security, since an attacker isn't limited to using your UI at all. Every trust boundary this lesson describes needs to be enforced on the server, where the attacker can't simply bypass it by crafting a raw HTTP request with a tool like curl or Postman instead of clicking through the intended UI.
The defensive posture this domain builds toward: validate, don't just hope
The recurring fix, across nearly every lesson in this domain:
- VALIDATE untrusted input against exactly what's actually expected
(not just "reject obviously bad stuff" — accept ONLY the known-good shape)
- Treat every trust-boundary crossing as a genuine control point,
not a formality
- Assume anything NOT explicitly validated is hostile until proven otherwise
The specific mechanisms in the rest of this domain — parameterized queries for SQL injection, output escaping for XSS, CSRF tokens, origin validation for SSRF — are all instances of the same underlying discipline: identify where untrusted data crosses into your system, and enforce a genuine check at that exact point, rather than trusting it because it "usually" looks fine or because the UI that produced it seemed to constrain it. This mental model — find the trust boundary, verify what crosses it — is the one piece of intuition worth carrying into every other lesson in this domain.
Further reading
Check your understanding
A quick comprehension check — not tracked, not graded, just for you.
1. What is a 'trust boundary,' and why does it matter for security?
2. Why is 'attack surface' usually larger than what a feature's own UI suggests?
3. Why is client-side validation (a dropdown's fixed options, a required form field) not a real security control?