RC RANDOM CHAOS

Your build trusts whatever it can find

A build system executed code because a name resolved, not because content was verified. How trust attaches to the reference and outlives the artifact.

· 8 min read
Your build trusts whatever it can find

A build system requested a package by name and version, resolved that reference against a registry, retrieved the content the reference pointed to, and executed it inside a trusted environment. The reference matched. The retrieval succeeded. The execution proceeded under the same privileges granted to every other component the build was already trusting. No additional gate stood between the resolution of the name and the running of the code. The system did what it was constructed to do, in the order it was constructed to do it, and produced the outcome that order guarantees.

The execution was not an exception inside the pipeline. It was the pipeline. A reference came in, the reference was resolved, and the resolved artifact was treated as authorized by the fact of having been resolved. The act of locating the content stood in for any assessment of the content. There was no point in the sequence where the system paused to ask whether the thing it had retrieved was the thing it intended to trust. The sequence had no such step, because the sequence had never needed one to function.

What is worth holding onto here is not that something malicious ran. It is that nothing abnormal happened from the system’s perspective. The retrieval was routine. The match was clean. The execution was expected. Every observable behavior was the behavior the system was designed to produce. The result was indistinguishable, at the level of system action, from ten thousand prior runs that ended without incident. The behavior did not deviate. The conditions underneath it did.

It did not start this way as a vulnerability. It started as a convenience. The system was built on a single assumption, and the assumption was that a name plus a version is a stable identity. That a reference, once it resolves to content, points at fixed content. That if the same coordinates were requested again, the same thing would arrive, and that the thing’s earlier acceptability carried forward to every later retrieval of the same coordinates. Trust was attached to the reference, not to the content the reference happened to be holding at any given moment.

The assumption extended further than identity. It assumed trust was persistent: once a dependency had been deemed acceptable, it stayed acceptable, and that judgment did not expire. It assumed trust was transferable: acceptability established for one version flowed forward to the next, and acceptability established at one moment flowed forward to the next moment without renewal. The system did not store a verdict about a specific artifact. It stored a relationship to a name, and treated the name as a proxy for everything the name had ever pointed to.

This is an efficient design, and it is efficient precisely because it removes work. Resolving a reference is cheap. Verifying content is expensive. A system that verifies on every retrieval pays that cost on every retrieval, forever, for an answer that is almost always the same. So the system optimized for reference. It resolved the name, confirmed the coordinates, and moved on. The artifact became the objective. Possession of the correctly named thing became the entire definition of having the right thing, and the registry of names became the registry of trust.

What changed was not the attacker, and not anyone’s diligence. What changed was the validity of the assumption. The relationship between the reference and the content it pointed to was never guaranteed by the system. It was guaranteed by conditions outside the system: by the registry behaving as it always had, by the coordinates resolving to what they had resolved to before, by the past remaining a reliable description of the present. Those conditions held until they did not. When they stopped holding, the reference kept resolving exactly as cleanly as before.

The system did not re-evaluate trust when the content behind the reference changed. It had no mechanism to notice the change, because noticing was the work the design had deliberately removed. It inherited trust from a prior state, a state in which the name and the content had agreed, and it carried that inheritance into a present where they no longer did. The verdict it acted on belonged to an artifact that no longer existed at those coordinates. The reference was current. The trust was historical. The system applied the historical trust to the current content and called the two the same.

That assumption no longer holds, but the system was never told. Nothing in its observable behavior could distinguish a reference that still pointed at trustworthy content from one that pointed at content the original trust was never extended to. Both resolved. Both matched. Both executed. The gap that opened was not a gap in capability or attention. It was the gap between what the reference asserted and what the content actually was, and the system was built to never look into that gap, because for most of its operating life the gap did not exist.

The failure was not a break in the sequence. It was the sequence completing. The pipeline was constructed so that the resolution of a reference produced the authorization to execute, and those were not two events with a check between them. They were one event. The name resolved, and resolution was the grant. Nothing in the observable behavior of the system marked a transition from located to permitted, because no such transition was ever present in the sequence. The artifact arrived carrying the authority of its coordinates, and the coordinates were the only credential the system ever read.

Identity of source stood in for integrity of content. The system confirmed that the content came from where the reference said it would come from, and treated that confirmation as equivalent to a confirmation of what the content was. Provenance answers a question about location. The system read it as an answer about character. Those are different questions, and the design collapsed them into one, because across the entire operating history of the pipeline the location had reliably predicted the character. The proxy held until it was the only thing still being measured, and then the thing it stood for moved out from under it without disturbing the measurement.

What ran was expected behavior, not a bypass. A bypass implies a control that was evaded, a gate that was gone around, a path that was not meant to be open. There was no such control to evade. The content ran along the path every prior artifact had run, under the privileges every prior artifact had carried, producing the system actions every prior run had produced. The match was clean. The retrieval succeeded. The execution proceeded. From the outside, this resolution was indistinguishable from the ten thousand before it. The single variable that had changed was the content behind the reference, and content was the one variable the system was built never to read.

The gap between assertion and fact was not crossed by the attacker. It was never closed by the system. A reference asserts what should be at a location. The content is what is actually there. The pipeline acted on the assertion and never compared it against the fact, because comparing them was the cost the design had been built to avoid. The verdict it executed belonged to a prior state in which assertion and fact agreed. It applied that verdict to a present in which they did not, and reported success, because at the level of system action success was exactly what had occurred.

The pattern is execution based on reference rather than verification. A system is handed a pointer. It resolves the pointer to a thing. It then acts on the thing as though resolving the pointer had established what the thing is. The pointer carries authority the content was never individually granted. Trust attaches to the coordinate, the name, the handle, the address, and flows automatically to whatever currently occupies that location. The system does not ask what is there. It asks only whether something is there, and treats the affirmative as sufficient. This is not a defect peculiar to build pipelines. It is the shape of any system that has decided that locating the right thing and possessing the right thing are the same act.

The same mechanism settled the financial system in 2008. An instrument was acquired and held because it carried a rating, and the rating was a reference. It pointed at an assessment performed once, against assets that existed at one moment, under conditions assumed to persist. The institutions holding the instrument did not re-verify the loans underneath it on each settlement. They resolved the rating, confirmed it matched, and treated the match as a statement about the content. The rating was the coordinate. The portfolio was whatever the coordinate currently pointed to. Acceptability established for the reference flowed forward to content the original assessment had never seen.

When the assets behind the rating decayed, the rating kept resolving exactly as cleanly as before. Nothing in the routine behavior of the settlement system could distinguish a reference that still pointed at sound content from one that pointed at content the original trust was never extended to. Both resolved. Both matched. Both cleared. The reference was current and the validity was historical, and the system applied the historical validity to the current content and called the two the same. The instrument did not change in name. It changed in what the name was holding. The mechanism that ran the build and the mechanism that cleared the trade are not similar. They are identical. Reference resolved, content unread, prior trust replayed against a present it never described.

A reference is a promise that something has already been decided. The system that acts on it is not deciding. It is remembering.

The system resolves trust once. It does not revalidate. Every later execution is that first decision replayed, applied to content the first decision never saw.

This is not a flaw in the system. It is the system. The control exists. The outcome does not.

Share

Keep Reading

Stay in the loop

New writing delivered when it's ready. No schedule, no spam.