Dev News Daily ENDE

A registration is an attack surface even with nothing behind it

The most useful bug of the week had nothing behind it. The Windows privilege escalation in Project Zero's writeup was a COM object registered system-wide whose server DLL did not exist — it pointed at a path inside C:\ProgramData, where any user can create files. The exploit was to create the file the system had promised was there.

That shape is worth lifting out of COM, because it recurs everywhere a system resolves a name to a location:

A dangling reference to a writable path is a latent bug, present or absent server. The registration is the surface. Whether anyone ever shipped the thing it names is irrelevant to the attacker who can supply it. PATH entries pointing at world-writable directories, LD_LIBRARY_PATH in a setuid context, a service unit referencing a script under /tmp, a container image that COPYs from a build arg — all the same class: a resolver that will load whatever is at a location you control.

A registration is an attack surface even with nothing behind it
A registration is an attack surface even with nothing behind it — Dev News Daily

"Incomplete fix" is the normal outcome of fixing the loader instead of the reference. This CVE existed because an earlier fix closed one way to load the dangling object and left the object dangling; a second loader reached it. When the cause is a bad reference, patching the path that reached it this time leaves the next path open. The durable fix removes the reference or makes the location unwritable.

The audit is mechanical, which is the good news. You do not need to find the exploit to find the exposure. Enumerate the resolvers a privileged process trusts — registry CLSIDs, library search paths, unit files, plugin directories — and for each, ask whether any entry resolves to somewhere a lower-privileged user can write. Every "yes" is a bug whether or not anyone has written the payload yet.

The engineer's version of the rule is short: a name is only as trustworthy as the most writable place it can resolve to. The COM object was trusted by every service on the machine; the place it resolved to was trusted by no one. That gap is the vulnerability, and it does not need a DLL to be real.