Episode 1 · 8 August 2026 · Marcus Hale, Tess Calder

Local or Network? On the Temptation of a Simple Split

A dialectic conversation between Marcus and Tess on whether known vulnerabilities should be divided into those exploitable over the network and those exploitable only locally — and what such a division would do to the people who have to act on it. AI-narrated.

Episode 1 8 August 2026 22:04

Show notes

Shownotes hier ergänzen.

Transcript

— I. The Proposal —

Marcus Hale: I want to put a proposition to you, and I want you to take it seriously before you take it apart.

Tess Calder: That is a generous order of operations. Go on.

Marcus Hale: We are drowning. Not metaphorically — arithmetically. The number of published vulnerabilities grows every year, our product surface grows every year, and the number of analysts does not. The backlog is not a queue we are working through. It is a reservoir we are adding to.

Tess Calder: No argument so far.

Marcus Hale: So I want a first cut. Something cheap, something stable, something I do not have to litigate with every product owner. And I think it is already sitting in the data: divide known vulnerabilities into two classes. Those known to be exploitable over the network, and those known to be exploitable only locally. Two classes, two clocks. The network class gets an emergency response. The local class goes into the ordinary patch cycle.

Tess Calder: You mean the attack vector metric. AV:N against AV:L.

Marcus Hale: I mean the idea behind it, but yes — the metric is already there, it costs me nothing to read, and it does not require an analyst to think. That is the entire appeal. Every other prioritisation scheme I have been sold requires someone to sit down and reason about a specific vulnerability in a specific deployment. This one is free.

Tess Calder: And the justification? Not the operational one — the argument. Why should the world care where the attacker is standing?

Marcus Hale: Because of what each class presupposes. A network-exploitable vulnerability presupposes nothing. The attacker needs a route and a packet. A locally-exploitable vulnerability presupposes that the attacker is already there — already executing code, already holding a session, already past whatever we built to keep them out. Which means the local class is downstream of some other failure. Fix the failures that let people in, and you starve the local class of its preconditions.

Tess Calder: That is a real argument. It is the one I want to spend the evening on, because I think it contains a beautiful mistake.

Marcus Hale: Of course it does.

— II. The Vector Belongs to the Deployment, Not the Vulnerability —

Tess Calder: Start here. Take a local privilege escalation in a common system library. Same CVE, same vector string, three customers. The first runs it on a laptop that one person uses. For the attacker to exploit it, they must already own that laptop, and if they own the laptop they have already got what they came for. The vulnerability is nearly irrelevant. The second runs it on a Kubernetes node shared by four tenants. Local means any workload on that node. The vulnerability is the difference between a container and a cluster. The third runs it on a build runner that executes code from every pull request opened by a stranger on the internet. Local means anyone with a GitHub account. Which of those is a local vulnerability?

Marcus Hale: All three, by the metric.

Tess Calder: And how many of them are second-tier?

Marcus Hale: One. Possibly.

Tess Calder: So the vector did not tell you what you thought it told you. It described the vulnerable component in isolation, on the assumption of some notional reference deployment. It did not describe your customer. The scoring frameworks are honest about this — that is precisely why they carry environmental modifiers alongside the base metrics. The base score is a starting point that expects to be revised, and we have collectively agreed to treat it as a verdict because revising it is expensive.

Marcus Hale: Grant me that the CI runner case is exotic.

Tess Calder: It is not exotic, it is the default architecture of software delivery in 2026. And it inverts your premise completely. Your argument was that local presupposes a prior compromise. On a build runner there is no prior compromise. Executing untrusted code is the advertised function of the system. The attacker does not have to break in. They are invited in, by design, and the local vulnerability is the only thing standing between the invitation and your signing keys.

Marcus Hale: The runner is a boundary I depend on.

Tess Calder: Say that again, because you have just said the important thing.

Marcus Hale: The runner is a boundary I depend on. Container isolation is a boundary I depend on. The hypervisor is a boundary I depend on. And every one of those boundaries is defended by code whose vulnerabilities are, in your notation, local.

Tess Calder: Container escape: local. Hypervisor escape: local. Browser sandbox escape: local. Kernel privilege escalation: local. These are not the leftovers of the vulnerability world. They are the load-bearing walls of every multi-tenant system anyone has built in the last fifteen years. A scheme that sends all four to the ninety-day queue is not a triage scheme. It is a demolition plan with a schedule.

— III. Chains —

Marcus Hale: Take the second half of my argument, then. Even granting the boundary cases — starve the preconditions and the local class does not fire.

Tess Calder: How many real intrusions have you read the write-up for?

Marcus Hale: Enough.

Tess Calder: Then you know they do not have one step. Initial access, then escalation, then persistence, then lateral movement, then whatever the actual objective was. Initial access is very often network — an exposed edge device, an unpatched gateway, a credential that should not have worked. Everything after it is local. Escalation is local. Credential theft from memory is local. Escaping the container the initial foothold landed in is local. Your scheme prioritises step one of the chain and defers steps two through five. But step one only ever gets an attacker a shell as an unprivileged service account inside one container. It is steps two through five that turn that into a company.

Marcus Hale: So I am prioritising the door and neglecting the interior.

Tess Calder: You are prioritising the door on the assumption that the door will hold. And you know how that assumption performs. It is worth looking at what actually appears on the published lists of vulnerabilities observed being exploited in the wild — a substantial share of those entries are local escalations, precisely because they are the indispensable second move. Attackers do not respect our taxonomy. They do not decline to use a vulnerability because it scored a lower severity in someone's spreadsheet.

Marcus Hale: Then let me narrow. I am not proposing to ignore the local class. I am proposing a difference in clock. Network: hours. Local: the next scheduled release.

Tess Calder: And the moment you publish that policy, you have told every adversary exactly how long they have. You have created a durable, advertised, ninety-day window in the middle of every attack chain. This is the oldest failure mode in measurement: the metric changes the thing it measures. Declare a class of vulnerability second-tier and you have not made it less dangerous. You have made it more attractive, because you have guaranteed its availability.

Marcus Hale: You are describing an adversary who reads our policy documents.

Tess Calder: I am describing an adversary who reads our patch cadence, which is a policy document written in a language they find much easier to read.

— IV. Where the Distinction Frays —

Marcus Hale: Give me the edges, then. If I am going to abandon this I want to abandon it for good reasons and I want to know exactly which ones.

Tess Calder: Then take them in order. First — network does not mean internet. This is the one that will hurt you most in practice, and it will not hurt you technically, it will hurt you politically. The vector says the attack is delivered across a network layer. It does not say which network. An internal-only service, unreachable from outside, still scores as network-exploitable. But when you put the words "network exploitable" in front of a management audience, they hear "reachable from the internet," and they will fund accordingly. You will have built a classification that is systematically misread by exactly the people who allocate your budget. Vector is not exposure. They are different questions, and your two-bucket scheme quietly collapses them into one.

Marcus Hale: And the converse is worse. Something genuinely internet-facing but only locally exploitable gets filed as calm.

Tess Calder: It does. Second — the middle disappears. A binary throws away adjacent-network and physical. That is tolerable for a web application. It is not tolerable in operational technology, where the adjacent bus is the threat model, and it is not tolerable in automotive, where physical access to a connector is a Tuesday afternoon for a researcher and an entire product line for an attacker. You will have designed a taxonomy that works for the systems you happen to run and fails for the systems your customers happen to run. Third — the attacker is sometimes already local, permanently, by design. Consider anything you ship into someone else's hands. A meter, a set-top box, a vehicle, a payment terminal, a games console. For these, the adversary is not trying to become local. They bought the device. Local access is their starting condition, not their objective. Every locally-exploitable vulnerability in that product is, from the attacker's seat, a network-exploitable one — because the network they need is a screwdriver.

Marcus Hale: That inverts the whole scheme for an entire product category.

Tess Calder: It does, and note that it inverts it for the category where PSIRT obligations are heaviest and where you can least afford to be wrong. Fourth — the inverse case. An air-gapped or heavily segmented environment. There, your network class is largely theoretical and your local class is the real one. Same taxonomy, opposite ranking. Any classification that reverses its own ordering depending on architecture is not a classification. It is a description of one architecture. Fifth — libraries do not know how they will be used. A vector assigned to a library assumes a reference pattern of use. Your product may expose the vulnerable path over an API, or may compile it out, or may never call it. The vulnerability inherits its true vector from the consuming application, not from the component. And the vector recorded in the public database was assigned by someone who had never seen your application. Sixth — "known to be exploitable" is not one claim. Your proposal says known exploitable. Known how? A proof of concept exists somewhere? A weaponised, reliable exploit is being sold? It has been observed being used against real victims? Those are three completely different epistemic states, and the industry has three completely different instruments for them — a catalogue of what has been observed in the wild, a probabilistic score for what is likely to be exploited soon, and the vector itself, which describes only what would be required. Your two-bucket scheme has one unresolved distinction on its face and a second one hidden inside the word "known."

Marcus Hale: That last one is fair and it is mine to answer. I was using "known exploitable" loosely.

Tess Calder: Everyone does. It is why the term has stopped carrying information.

— V. The Turn —

Marcus Hale: So I concede the binary. But I do not concede the impulse. I still have a reservoir and I still have no analysts. Tell me what the distinction is actually for, because I do not believe it is worth nothing.

Tess Calder: Now we are somewhere useful. I think you have been reading it as a statement about severity, and it is not. It is a statement about precondition.

Marcus Hale: Meaning.

Tess Calder: The vector does not tell you how bad a vulnerability is. It tells you what an attacker must already possess before the vulnerability becomes usable at all. Network: they must possess a route. Local: they must possess a position. That is not a priority. That is an entry condition.

Marcus Hale: And an entry condition is only meaningful against something that is supposed to prevent it.

Tess Calder: Which is the whole point. A precondition is only informative in relation to a boundary. "Requires local access" is useless on its own and enormously informative the moment you ask: which of my boundaries is supposed to prevent local access here, and how much am I relying on it?

Marcus Hale: So the correct pairing is not vector against severity. It is vector against trust boundary.

Tess Calder: Yes. And that reframing does something your binary could not: it composes. It turns a flat label into a question with an answer that differs per deployment — which is correct, because the answer genuinely does differ per deployment.

Marcus Hale: Then let me try to rebuild it. Not two buckets. Three. One. Exploitable with no prior position. The attacker needs a route and nothing else. This is the emergency class and it always was. Two. Exploitable only from a position, but the position is one that a boundary I depend on is supposed to deny. Container escape on shared infrastructure. Escalation on a multi-tenant host. Anything on a build runner. Anything at all on a device the customer physically holds. This class is nominally local and operationally identical to class one, and I would have thrown all of it into the ninety-day queue an hour ago. Three. Exploitable only from a position that grants nothing I was not already conceding. Escalation on a single-user workstation where the foothold was already the whole prize. This is the class that can genuinely wait.

Tess Calder: And the second class is the one your original scheme was going to destroy you with.

Marcus Hale: It is the entire middle of the problem.

Tess Calder: One more thing, since you are a product person and not only an operator. There is an asymmetry between our two chairs that your proposal did not account for.

Marcus Hale: Say it.

Tess Calder: You do not know the deployment. I do. You ship into a thousand architectures you have never seen, and no amount of analysis on your side can tell you whether local access is trivial or impossible in any given one of them. So the classification cannot be your output. What you owe is the precondition, stated precisely — what an attacker must hold, which configurations are affected, which are not. Machine-readable if possible, so it can be consumed rather than read.

Marcus Hale: And the operator does the ranking.

Tess Calder: The operator is the only party who can do the ranking, because the ranking is a fact about their architecture. When you try to do it for them, you are guessing, and your guess arrives with the authority of the vendor attached — which makes it worse than no guess, because it stops them from thinking.

Marcus Hale: So my side produces preconditions. Your side produces positions. The priority is the intersection.

Tess Calder: That is the whole discipline in one sentence, and it is the sentence your two buckets were designed to avoid having to say.

Marcus Hale: Then let me claim what I can still keep, because I refuse to leave with nothing.

Tess Calder: Claim it.

Marcus Hale: First — as vocabulary it is excellent. Half my inbound support load is a customer panicking about an advisory. "Requires local access to the device" resolves a great many of those conversations in one line, honestly, without minimising anything. That is real value, and it is communication value, not prioritisation value. I had conflated the two.

Tess Calder: Agreed, with one condition: it must never be used to close a conversation. It is context, not reassurance.

Marcus Hale: Second — as a cheap prefilter it survives, but only in combination and only in one direction. Observed-in-the-wild overrides everything; if it is on that list the vector is irrelevant. Probability of near-term exploitation tilts the ordering within a bucket. And the vector supplies the precondition. None of the three works alone, and I had been shopping for one that would.

Tess Calder: And the third thing?

Marcus Hale: Third, and this is the one I did not expect. As a metric the split is genuinely interesting — just not as a prioritisation metric. If I track the size of my locally-exploitable backlog on systems where a boundary depends on it, I am measuring something no other number tells me: how much damage one foothold would do. Not how likely I am to be breached. How expensive the first breach would be.

Tess Calder: Blast radius debt.

Marcus Hale: Blast radius debt. And I would bet a considerable amount that mine has been growing for three years, silently, because every scheme I have used treats those items as the ones that can wait.

— VI. Tess Summarises —

Tess Calder: Let me put the whole thing in order, then, before either of us pretends we invented it. The proposal was to split known vulnerabilities into network-exploitable and local-exploitable, and to run two clocks. It fails in that form for six reasons. The vector is a property of the deployment, not of the vulnerability — the same CVE is a nuisance on a laptop and a cluster compromise on a shared node. Network does not mean internet, and the phrase will be misread by the people who fund the work. The binary discards the adjacent and physical cases, which are the entire threat model in operational and automotive contexts. Local presupposes a foothold only where a foothold is scarce, and on build infrastructure, in multi-tenant systems, and on any device the customer physically holds, it is not scarce at all. Attacks are chains, and the local class is the second through fifth links of nearly every one of them. And publishing the split creates an advertised window that the adversary will occupy. But the distinction is not worthless. It was simply being asked the wrong question. It does not measure severity. It states a precondition — what an attacker must already hold. A precondition is meaningful only against a boundary, so the useful pairing is vector against trust boundary, not vector against severity. From which follow three things. A three-way split rather than two, where the decisive middle class is the locally-exploitable vulnerability that defeats a boundary you are relying on. A division of labour, where the vendor publishes preconditions precisely and the operator, who alone knows the architecture, performs the ranking. And a metric worth having, which is the size of the boundary-defeating backlog — the cost of the first foothold, which no severity score has ever reported. The distinction is real. It is an input. It was never a decision procedure, and the appeal of treating it as one is exactly proportional to how tired we are.

— VII. Marcus Concludes —

Marcus Hale: I came in wanting a rule that would let me stop thinking, and I want to be honest that this is what I was actually asking for. Not a better model — a smaller one. Something that would let me say this class waits without anyone, including me, having to justify it. That instinct is not shameful. It comes from a real constraint. The volume is genuinely beyond what deliberation can absorb, and anyone who tells a PSIRT lead to simply analyse each case more carefully has not counted the cases. The pressure to compress the problem is legitimate. But I now think there are two kinds of simplification and I had not been distinguishing them. One kind removes work by removing questions that did not need asking. The other removes work by declining to ask questions that did. The local-versus-network split looked like the first and is the second. It does not compress the problem. It relocates it — from my queue, where it is visible and someone is accountable for it, into my architecture, where it accumulates quietly and surfaces only once, in a form nobody schedules. So the distinction stays, in three roles, and none of them is the one I proposed. It stays as language — because "requires local access" tells a customer something true and useful, and I should say it more often, and never as a way of ending the conversation. It stays as one input among three — after what has been observed in the wild, alongside what is likely to be exploited soon, and always read as a precondition rather than a verdict. And it stays as a measurement I was not previously taking — the volume of locally-exploitable findings sitting on top of boundaries I am relying on. That number is the price of the first foothold, and I have never once been asked for it, which is probably why it is as large as I suspect it is. What it does not become is a clock. Two clocks would have felt like control and would have been a schedule published to the adversary. Tess, my honest summary is this. I asked whether we should sort vulnerabilities by where the attacker has to stand. The better question was what the attacker has to hold, and which of my walls was supposed to be holding it. Those are not the same question, and only the second one has an answer I can act on.

Tess Calder: And the reservoir?

Marcus Hale: Still full. But I now know which part of it is load-bearing, and that is more than I knew this morning.