tlctc.net / blog 2026-05-15 · Glossary Fix
TLCTC Glossary Fixes · Entry 01
↗ Series index
Terminology · Cause-Side Discipline

"Local Exploit" Is Not a Threat Category

It is a precondition descriptor. It tells you where the attacker stands, not what they exploit. The structural cause is always one of three clusters — and it is always mid-chain.

A "local exploit" is one of those terms that does useful work right up to the moment it gets promoted out of its job description. Used as a vector qualifier — "this CVE requires local access to trigger" — it is precise and helpful. Used as a threat category — slotted next to "remote code execution" and "phishing" in a list of things to defend against — it hides more than it reveals. The category sense is what this entry fixes.

§ 1The term in the wild

Three usages circulate, and they are routinely conflated.

The first is the CVSS sense: Attack Vector AV:L. This says the attacker must already have local access to the target — no network reach, no remote authentication bypass, no drive-by trigger. It is a precondition statement about access topology. It is unambiguous and useful.

The second is the outcome label: "local privilege escalation," "LPE," "local EoP." This says the attack ended at a higher local privilege than it began. It is a statement about the consequence side of the bow-tie, anchored to whatever boundary got crossed inside the host.

The third is the one this entry attacks: "local exploit" used as a threat-category label, appearing in the same conceptual slot as things like "buffer overflow," "phishing," "malware," "supply-chain attack." A document that lists these alongside each other as if they were peers is committing a category error. The first three name causes. "Local exploit" names a position.

§ 2Why it fails the TLCTC test

Two structural failures, each sufficient on its own.

First, "local" is a precondition, not a cause. Under Axiom III, threats are causes. Cause-side analysis answers what generic vulnerability is being exploited. The fact that the attacker must already be on the box to trigger the exploit tells defenders something true about access requirements, but it tells them nothing about which code path fails, which interaction direction is involved, or which class of control would prevent it. A precondition is not a cause. The framework's SG-4 guardrail extends naturally here: positional and pre-conditional descriptors are not threats any more than outcomes are.

Second, "local exploit" is structurally mid-chain. By its own definition the term presupposes that the attacker has already achieved local access. Initial access is the step before. That means "local exploit" cannot be the first step of any attack path. Something else — phishing, malware delivery, physical access, supply-chain compromise — sits to its left. A taxonomy of strategic threat categories has to admit every step in a chain, including the first one. A label that can never occupy the first position is not a top-level category; it is at best a sub-tag that attaches to clusters when they appear post-foothold.

§ 3The three decompositions

Every concrete CVE the industry calls a "local exploit" lands in exactly one of three TLCTC clusters, determined by the cause-side discipline of R-ROLE and R-EXEC. The framework is exhaustive on this point — there is no fourth option that "local exploit" smuggles in.

Legitimate function used in unintended context

No code flaw is exploited. The escalation comes from misconfiguration or designed-feature abuse — a function works exactly as intended, and the design itself permits the elevation. These cases often have no CVE at all because there is no bug to assign one to.

Examples   sudo NOPASSWD on a broad command set · writable directories in $PATH ahead of system paths · cron jobs invoking user-writable scripts as root · GTFOBins-style abuse of SUID binaries' designed write/exec capabilities · Docker-group membership granting effective root

Privileged code receives inbound stimulus, fails on the server side

Some local code path running at higher privilege accepts and processes inbound input — argv, environment variables, syscall arguments, IPC messages, IOCTL payloads, named-pipe messages — and the server-side handling code has an implementation flaw. The attacker sends; the privileged code receives and breaks. This is the most common decomposition by volume.

Examples   Sudo Baron Samedit (CVE-2021-3156, heap overflow in argv parsing) · Polkit PwnKit (CVE-2021-4034, argv/env handling in pkexec) · Dirty COW (CVE-2016-5195, kernel COW handling) · Dirty Pipe (CVE-2022-0847) · Calif M5 kernel chain (2026)

Privileged code fetches data, fails on the consumption side

A privileged process initiates a read or call, and the returned data — controlled or influenced by the attacker — is mishandled on the consumption side. The attacker does not send a request to the vulnerable code; the vulnerable code goes and gets something, and the something is hostile. Rarer than #2 in the local-exploit population but structurally distinct.

Examples   an in-kernel SMB/NFS client mishandling a hostile server's response · USB descriptor parsing during device enumeration · privileged daemons parsing attacker-writable config files · root services consuming untrusted library response data via dlopen-style chains

§ 4Why this matters: one label, three different defences

A defender working from outcome-anchored vocabulary sees "local privilege escalation" and reaches for a generic mitigation: patch faster, restrict local accounts, enable EDR. Those are not wrong, but they are not aimed. The three decompositions need different aim.

The #1 cases are not patchable — there is no bug. They are eliminated by configuration hygiene, least-privilege design, removal of unnecessary SUID bits, and strict PATH/cron review. The #2 cases are patched at the receiving handler and hardened at the syscall and IPC surface — argument bounds checks, environment sanitisation, server-side input validation. The #3 cases are patched at the response consumer and hardened by validating returned data before use — length validation on returned records and consumed buffers, distrust of all upstream-returned state.

An organisation that classifies all three as "local exploits" in its risk register will spend its budget on the most visible mitigation (usually faster patching) and systematically under-invest in the configuration discipline that eliminates the #1 bucket entirely. The label flattens the structural difference. The cluster preserves it.

§ 5The fix

Keep "local" as a CVSS-style vector qualifier where it earns its keep: AV:L in scoring, "requires local access" in advisories, "local-only triggerable" in risk modelling. Drop "local exploit" as a threat category. When a category-level statement is needed, name the cluster: #1, #2, or #3, with an intra-system boundary annotation if the elevation crossed an interesting trust line. The vector qualifier and the cluster live at different conceptual layers and answer different questions. The framework lets both stay useful by refusing to let them collapse into each other.

The diagnostic the cluster gives you that the label does not: which side of the failing operation the attacker controls. That is the question every defensive control eventually has to answer, and "local exploit" never does.◆