Threats5 min read

Software supply chain risk stops at the endpoint

Every supply chain compromise ends the same way, with a signed package executing on a managed device. What that means for endpoint security and Windows controls.

Every software supply chain compromise you have read about ends in the same place. Not in a repository, not in a build server, but on an endpoint, where a package that looks legitimate executes on a device somebody is using for work.

That is worth stating plainly because supply chain security is usually discussed upstream, in terms of dependency scanning, build provenance and vendor questionnaires. All of that is worth doing. None of it changes where the compromise lands.

Why the endpoint is the last checkpoint

Upstream controls are predictive. They assess whether something is likely to be safe before it arrives.

The endpoint control is different in kind, because by then the software is present and the only remaining question is whether it may run. On Windows that decision is made by code integrity in the kernel, below the level at which a user or a local administrator operates. It is the last place a decision can be enforced rather than recommended.

That is also why it is the control frameworks keep asking for, under different names. Application control mapped to the frameworks covers which ones and what each asks.

The uncomfortable part

Application control does not stop a supply chain attack, and it is worth being honest about that rather than selling past it.

If a vendor's build system is compromised and the malicious update is signed with that vendor's real certificate, a publisher rule allows it. The rule is doing exactly what it was written to do. The trust decision was made correctly, based on information that turned out to be false.

So the claim is not prevention. The claim is blast radius.

Most of these intrusions rely on a second stage. The initial package establishes a foothold and then pulls down or drops something else: a remote access tool, a credential harvester, a loader, a driver. That second stage is almost never signed by the same trusted publisher, because it does not come from the vendor at all.

An estate with application control enforced has already refused that second stage. The intrusion does not become nothing, but it becomes one compromised binary rather than a foothold that expands. That difference is most of the incident.

Stop asking what is dangerous covers why a control that starts from what is permitted behaves differently here from one that starts from what is known to be bad.

Signing raises the cost, which is the point

The obvious objection to signing is the one above: signatures can be subverted, so why rely on them.

Because the alternative is worse in every direction.

Unsigned software is an everyday problem. A compromised signing key is a rare, expensive, high effort attack carried out by capable actors against specific targets. Designing your controls around the second while ignoring the first optimises for the threat you are least likely to meet.

Publisher rules survive updates. A hash rule is exact and dies at the next release, which means a maintenance commitment for every version of every application forever. A publisher rule holds across releases. That durability is what makes an allowlist sustainable rather than a treadmill.

Signing makes provenance a question you can answer. Not perfectly, but the alternative is not answering it at all.

Signed and unsigned policies covers the same trade applied to the policy itself.

Patching cuts both ways

There is a tension here that most supply chain discussions skip.

Falling behind on updates leaves known, published, exploited vulnerabilities sitting on your fleet. Accepting every update the moment it ships means accepting whatever the vendor put in it, which is precisely the exposure this article is about.

Neither extreme is a policy. What resolves it is not choosing between them but controlling the path: knowing where a release came from, verifying it inside your own boundary, recording who accepted it, and delivering it through a mechanism you already trust.

That is the difference between staying current and simply accepting whatever arrives. An application that updates itself covers what happens when the path is the application's own updater instead.

Your own builds are a supply chain too

Internal line of business applications get treated as a different category, and they are not.

An internal build has dependencies it did not write, a pipeline that fetches them, credentials that can be stolen and artefacts that can be swapped. It has all the same properties as a vendor's supply chain, with the difference that nobody is auditing it and it usually arrives unsigned.

Applying the same standard to what you build as to what you buy is the consistent position, and it is a good deal easier to argue internally than an exception carved out for your own software.

What this means in practice

Four things, in order of how much they change.

Make the execution decision enforceable. Everything upstream is advisory once the package is on the device. Kernel enforced code integrity is the checkpoint that holds.

Prefer publisher rules to hash rules where the software is signed, and treat code signing as a purchasing question rather than a technical one. Who application control involves covers why that belongs with procurement.

Control the path updates arrive by, so staying current does not mean accepting whatever a vendor shipped without anybody looking.

Hold internal builds to the standard you hold vendors to, because the pipeline you own is the one you can actually inspect.

Where PoliEze fits

PoliEze governs the execution decision across the estate: what is allowed to run, who approved it, when that approval was made and what changed since. PoliEze Flow covers the other half, giving each release a controlled path from discovery to deployment so software stays current without the trusted set widening to accommodate it. Together they mean a supply chain decision is one somebody made deliberately rather than one that happened by default.

Questions about this

Does application control stop a supply chain attack?
Not on its own, and anyone claiming otherwise is overselling. A compromised update that is properly signed by a vendor you trust will satisfy a publisher rule. What application control changes is the blast radius, because it removes the untrusted second stage, which is where most of these intrusions do their actual work.
If signing can be subverted, why sign at all?
Because the alternative is worse. Publisher rules survive updates where hash rules break at every release, and a compromised signing key is a rare, high effort attack while unsigned software is an everyday one. Signing raises the cost of the attack rather than removing it.
What is the endpoint control that actually matters here?
Controlling what may execute, and knowing what did. A supply chain compromise ends with code running on a device, so the last enforceable checkpoint is the execution decision on that device, which on Windows is code integrity in the kernel.
How does patching interact with supply chain risk?
It cuts both ways, which is why the path matters. Falling behind on updates leaves known vulnerabilities exposed, and accepting every update automatically means accepting whatever the vendor shipped. A governed path lets you stay current while still deciding what enters the estate.
Where do internally built applications sit in this?
In the same place. Your own build pipeline is a supply chain, with its own dependencies, its own signing and its own opportunities for something to be introduced. Applying the same controls to what you build as to what you buy is the consistent position.

Related reading

Stuck on the thing this article describes?

If you are working through this on a real fleet and it is not going the way the documentation suggests, that is the conversation we are best at. Send us the block events.