Why
Security is usually taught as a list, and a list is the wrong shape for the subject. The lists are real and worth knowing, but they are a catalogue of instances, and instances age: a vulnerability class that dominated one decade is a solved configuration default in the next. What does not age is the question underneath every entry, which is always some version of the same one — something crossed a line that somebody believed was a line.
This catalogue happens to contain the evidence, which is why the claim is not just an aphorism. Six cards written for unrelated reasons made the identical move. third-party-blast-radius found that the boundary drawn around a frontend excluded the vendor whose script the frontend loads, and that the reflex controls both answer the wrong question, since the script was authorized. storage-collision-admin-takeover found two modules that each believed they owned a storage slot. pick-a-signer-not-a-brand found that a brand name is four supply chains, only one of which anyone audits. what-encryption-does-not-hide found that hiding the amount leaves the graph. huggingface-is-a-package-manager found that a load option is an execution grant. demonstration-is-not-a-specification found that granting an assistant sight of a task grants it sight of the screen. Six different subjects, one move, and none of them needed a vulnerability list to reach it.
Stated plainly, the method is two questions asked in order. First: where is the boundary, what is inside it, what is outside, and who gets to decide. Second: what crosses it, and what can the thing that crossed do once it is across. Nearly every real finding is the second question answered carefully after the first was answered casually — and the reason the casual answer survives so long is that the check people actually run, "is this authorized", returns yes at exactly the moment of the attack. The vendor was on the allowlist. The module was deployed on purpose. The flag was set by the person who needed it set.
The honest limit of this card is that some things do have to be memorised, and pretending otherwise would be the same error in the opposite direction. There is a small recurring set of places where authorized and safe come apart, and they are worth knowing by name because they are structural rather than incidental: anything that executes code arriving as data, anything that runs in someone else's storage or memory context, anything that deserialises untrusted input, anything that evaluates a template or expression, and any request made by your server on behalf of a caller, since your server is inside the perimeter and the caller is not. Those are shapes rather than bugs, and a boundary diagram plus that short list covers more ground than a long list alone.
Finally, the reason to study it this way rather than the comfortable way. A list gives the feeling of coverage and no way to check it. A boundary diagram is falsifiable: someone can point at it and say the line is in the wrong place, or that a crossing is missing, and that argument is productive in a way that comparing checklists never is. The output of studying security should be a thing someone else can attack on paper, and a list of attack names is not that thing.
How it works
Six cards, one move
| Card | The boundary that was assumed | What actually crossed it |
|---|---|---|
third-party-blast-radius |
"our frontend" | A vendor's script from the vendor's own infrastructure — so SRI and CSP both pass |
storage-collision-admin-takeover |
"each module owns its state" | Two modules, one slot, two meanings |
pick-a-signer-not-a-brand |
"the device" | Entropy path, per-chain app, fulfilment partner |
what-encryption-does-not-hide |
"the amount is the secret" | The graph of who paid whom, and when |
huggingface-is-a-package-manager |
"loading a model" | trust_remote_code executes repo code in your process |
demonstration-is-not-a-specification |
"it watches the task" | It watches the screen |
None of these were found by consulting a vulnerability list, and that is the argument. They were found by asking where the line was and what was on the other side of it.
The two questions, and why the usual one fails
| Question | What it catches | Why it is not enough |
|---|---|---|
| "Was this authorized?" | Unauthorized access | Returns yes during the attack. The vendor was allowlisted, the flag was set on purpose |
| "Where is the boundary?" | Boundaries drawn too small | Needs the second question to become actionable |
| "What can it reach?" | The blast radius of an authorized component | This is the one that produces findings |
The short list that does have to be memorised
Boundary thinking is the method, but a few shapes recur often enough to know by name — all of them places where authorized and safe come apart:
- Code arriving as data, then executed —
trust_remote_code, plugin loaders, dynamic imports - Running in someone else's context — delegatecall, shared storage, injected scripts
- Deserialising untrusted input — the object graph is a program
- Evaluating templates or expressions — the interpreter is the vulnerability
- Requests your server makes for a caller — your server is inside the perimeter; the caller is not
These are shapes rather than bugs, which is why they survive the churn that retires specific vulnerability names.
The order to study in
- Draw the boundary for one system you own. Inside, outside, and every crossing.
- For each crossing, write what it could do if hostile today. Capability, not origin — this is the sentence
third-party-blast-radiusbuilds its whole inventory on. - Then read the attack lists, as a coverage test. An entry that lands on a crossing tells you which control to check. An entry that does not land is either irrelevant here or a boundary you missed.
The reason for the order is that the list-first route produces recall and the model-first route produces a filter, and only one of those still works on a system nobody has written a list about yet.