Open-Source and the Path to the Client Runtime

Modern applications running inside Client Runtimes are mostly other people's code. A typical bundled application, whether it ships through a web origin, a mobile-app store, a desktop installer, a vehicle infotainment image, a smart-TV package, or a productivity-tool plugin marketplace, carries more open-source dependency code than application-authored code. The application owner writes the code that wires the pieces together; the rest comes from npm, PyPI, Maven, NuGet, crates.io, RubyGems, the package ecosystems for embedded runtimes, and the transitive dependency graphs each of those carries. The runtime that executes the assembled application cannot tell the application owner's code apart from the dependency code, and grants both the same trust at the rendering surface.

Traditional supply-chain security treats the open-source ecosystem as an upstream-of-build concern: vet the source, scan the package, sign the published package, monitor the registry. These controls are valuable, but they cluster at the registry and the build. By the time dependency code reaches a Client Runtime and starts executing on the rendering surface, almost none of them are still in force. The Client Runtime is where the user encounters the system, and where ATG operates.

Two properties make the open-source supply chain ATG-distinctive. The first is that the threshold for an adversary to acquire Placement and Access (P&A) inside an open-source project is structurally lower than the threshold for any other comparable supply-chain access route: the Open-Source Open Door. The adversary does not bypass trust the way a backdoor does; they are handed it, walking in the open door as an invited, trusted contributor or maintainer. Nothing is broken into; the door was open by design. The second is that once code from many sources is combined and loaded into the runtime, the record of which source supplied which part is gone. The runtime executes the bundle as one unit and cannot trace any part of it back to the project that wrote it. That is Origin Laundering. One script can build runtime code out of data supplied by another source, so the code that finally executes has no single author. As in money laundering, adversarial input passes through legitimate sources until no one can say where it started, and it moves along inside the clean flow. Each property defeats a different existing control. Together they decide what an open-source compromise is worth to an adversary once the code reaches the runtime.

9.1: Why Open-Source Matters for ATG

Open-source dependency code dominates what executes inside Client Runtimes. Public dependency analyses find that open-source components make up the large majority of modern codebases (Sonatype, State of the Software Supply Chain; Black Duck, Open Source Security and Risk Analysis). Both measure composition at the codebase level rather than inside a rendered bundle, and no public dataset measures the bundle directly. A bundle inherits that composition through the build, with the remainder divided between application-authored code and the build-tool output that links them. Mobile applications built on hybrid frameworks, desktop applications built on shells that wrap a web runtime (Electron, Tauri), vehicle infotainment systems running embedded JavaScript engines, IoT and operational technology (industrial control) dashboards built on web stacks, and productivity-tool extensions all carry comparable proportions. The host platform varies; the dependency dominance does not.

Adversaries reach that dependency code through entry vectors the broader supply-chain literature has documented in depth: maintainer credential compromise, new-maintainer takeover, long-game contributor infiltration, intentional sabotage by the original developer, CI/CD pipeline injection, dependency confusion, and typosquatting at ecosystem scale. Specific cases include XZ Utils, ua-parser-js, event-stream, node-ipc, and the Magecart-related open-source compromises.

What matters for ATG is what the compromised code can do once it is executing on the user's screen. Because most of the executing code is dependency code, an upstream compromise lands in a runtime that cannot tell the compromised dependency from code the application owner wrote, and gives it the same trust on the rendering surface. The registry-level and aggregation-level patterns operate upstream. The share of running code that comes from dependencies is what turns a compromise at the entry point into a consequence on the Glass.

9.2: The Open-Source Open Door

Open source is the dominant, legitimate, wide-open route by which code reaches the Glass, and acquiring Placement and Access (P&A) inside an open-source project carries a lower threshold than any other comparable supply-chain route. Most of what runs on the Glass is code no one on the target's payroll wrote. Employment requires hiring processes, background checks, identity verification, contractual relationships, and a continuing employment record. Vendor positioning requires a commercial relationship with a buyer or a recognized place in a procurement chain. Commercial acquisition requires capital and produces corporate-transaction visibility. Open-source projects routinely look for maintainers and admins from the contributor base, and they do so without any equivalent vetting infrastructure.

Three mechanics account for the low threshold:

  • Public recruitment: active "looking for maintainers" calls are common across the major package ecosystems. Projects with declining maintainer engagement, single-maintainer projects, and projects whose original developer has burned out actively seek volunteers.
  • Contribution as credential: sustained helpful contributions over months earn reviewer or commit privileges. The contribution history is the credential. No employment relationship, no background check, and no formal identity verification is involved at any step.
  • Single-decision transfer: for some projects, becoming a co-maintainer or sole maintainer requires only that the existing maintainer agrees. The transfer can happen in a single email exchange.
Figure 27: The lowest-barrier route to a rendering surface is contribution to something everyone already depends on.

XZ Utils (2024) demonstrates the pathway end to end. A single contributor, over years of legitimate-looking commits, earned reviewer access, then commit access, then effective control over a critical infrastructure project. No employment relationship, contractual structure, or commercial transaction stood between the contributor and project control.

Maintainer and admin positions hold authority over more than the commit log:

  • Project governance: the maintainer's voice is the dominant one in roadmap, design, and release decisions.
  • Publishing and release authority: the maintainer signs and publishes the next release. To the registry, that signature is the proof that the released package came from the project.
  • Community trust positioning: the maintainer's name and reputation vouch for the project, and downstream consumers, employers, conference programs, and adjacent projects rely on that.
  • Communication and documentation channels: the maintainer controls what the project tells its users: changelog framing, security advisory wording, deprecation timing, end-of-life notices.
  • Issue management: the maintainer decides which bug reports are recognized, which are reframed, and which are quietly dismissed.
  • Downstream relationship building: the maintainer position is a credential that opens doors to other projects, advisory roles, and offers of employment from companies that depend on the project. Open-source projects depend on community trust mechanisms (reputation, contribution history, code review) for access decisions. The mechanisms are designed to detect bad code in individual contributions; they are not designed to detect Adversarial Placement and Access (APA) by patient contributors with long-game intent. An adversary who wants insider access takes the cheapest route to it, and open source is the cheapest: the threshold for becoming the insider is lower there than on any other supply-chain access pathway.

9.3: The Path from Package to Rendering Surface

The path from open-source package to executing rendering-surface code is several layers deep, and the layers carry uneven controls. A maintainer publishes a package to a registry. The registry's controls cover signing, account integrity, and the response to maintainer compromise. An application's build process resolves the package, fetches the published files, and bundles them with the application's own code and the files of every other dependency it resolved. The build's controls cover dependency scanning, lockfile pinning, software-bill-of-materials generation, and integrity checks on the files it fetched. The bundle then ships through a distribution channel: a CDN for web origins, an app-store binary for mobile, an installer for desktop, an over-the-air channel that pushes code to vehicles, IoT devices, and smart TVs after they are already in service, without a store review in between, a marketplace listing for plugins and extensions. Each channel carries its own controls: code signing, store review, transport integrity. The host Client Runtime loads the bundle and executes its contents at the rendering surface. At that layer, the controls thin to almost nothing.

A package published to npm reaches an Electron desktop application through the same path it reaches a React web origin. A Python package published to PyPI reaches a Jupyter notebook front-end through the same path as it reaches a server-side service. A Java library published to Maven Central reaches an Android APK through the same path it reaches a desktop JAR. A Rust crate published to crates.io reaches a Tauri desktop shell or a vehicle infotainment image through the same path. The host platform determines which Client Runtime finally executes the bundle. The path is the same, and so is the way the controls thin out along it.

Two properties of the path are ATG-specific. The runtime cannot distinguish dependency code from application code at execution time. Any compromise that survives the build is granted application-level trust at the rendering surface, with the same access to runtime, storage, network, and device APIs the application owner's own code holds. Dependency code is the most common case of trusted-but-foreign code the runtime executes.

The runtime's other blind spot is provenance: it holds no record of where the code it is executing came from. It cannot answer which dependencies were used to build the bundle, what their published versions were, whether the code in the bundle matches what those projects published, or whether something was added to the bundle after the registry-published sources were resolved. Whatever list of contributing packages the build had, that list stayed at the build. The bundle itself is opaque to the runtime that loads it. The build knew where each part came from; none of that knowledge travels with the bundle to the rendering surface.

9.4: Origin Laundering

Dependency analysis examines one thing; the runtime executes another. Dependency tooling resolves the manifest (package.json, requirements.txt, Cargo.toml, Podfile, build.gradle) and reasons over what the manifest names. The bundle that ships is a different thing entirely, assembled by the build tool from the resolved dependencies plus everything the build added on top: transitive dependencies the declared packages pulled in, code generated by plugins or transforms, code the bundler copied in directly for performance, polyfills the build tool added, and package versions the resolution algorithm picked at dependency depths the manifest never records. The Client Runtime sees the bundle. It does not see the manifest.

A defender who validates the manifest validates the wrong thing. The manifest names the dependencies the application asked for; the bundle carries the versions that were actually resolved, plus everything the build tool added on top of them. Software-bill-of-materials generation that operates against the manifest produces an inventory of what the application asked for, not an inventory of what the bundle contains. Adversarial code introduced at any of the build-tool layers (plugin transforms, polyfill insertion, code the bundler copied in directly) lives in the bundle without appearing in the manifest. Compliance that rests on a software bill of materials assumes the bundle matches the manifest, and the build tool guarantees no such thing.

A defender who validates the bundle validates the static delivery, not the runtime behavior. Bundle hashes, code signatures, and Subresource Integrity tags answer one question: did the bundle that arrived match the bundle that was published. They do not answer what the bundle does once the runtime executes it. The Manifest Illusion and Runtime Anarchy operate inside the runtime, after the bundle has been validated and its contents have begun to execute. Bundle validation is necessary work, and Subresource Integrity does the job it was built for. Neither is sufficient at the runtime trust boundary.

The problem is invariant across bundle formats. A JavaScript bundle delivered to a browser, an iOS app binary delivered through the App Store, an Android APK delivered through Google Play, an Electron asar archive, an Office add-in package, an OTA update bundle delivered to a vehicle infotainment system, a smart-TV application package, a Tauri desktop binary: each is a unit of execution whose contents were composed at build time, and each is paired with a manifest the runtime never sees. The packaging differs. The split between what the manifest declares and what the bundle executes does not. That split is Origin Laundering: the bundle runs as one unit but carries no record of where its parts came from.

9.5: Plugin and Extension Marketplaces

Plugin and extension marketplaces carry a compromise to executing code on the user's screen more directly than any other open-source route. Developer-facing package registries deliver code into application bundles, where Origin Laundering applies but a build step at least exists and some controls run there. Plugin and extension marketplaces deliver code directly to end-user Client Runtimes. The user installs an extension or plugin and the code the marketplace published runs in the user's host application, against the user's data, on the user's device. No intervening build step exists for any control to operate at. Marketplace categories reach across the deployed platform landscape:

  • Browser extension stores: Chrome Web Store, Firefox Add-ons, Edge Add-ons, Safari Extensions Gallery.
  • IDE marketplaces: VS Code Marketplace, JetBrains Marketplace, Eclipse Marketplace.
  • Creative-tool plugin stores: Blender, GIMP, Maya, Houdini, FreeCAD.
  • Productivity add-in marketplaces: Microsoft AppSource (Office Add-ins built on Office.js), Slack App Directory, Atlassian Marketplace, Google Workspace Marketplace.
  • In-app extension and asset marketplaces in productivity, design, and creative tools: Figma plugins, Adobe Creative Cloud add-ons, Procreate brush packs, Lightroom presets, and analogous in-app marketplaces that publish executable or runtime-loaded behavior into the host tool.
  • Game-platform user-generated-content stores: Roblox UGC experiences, Steam Workshop (mods, maps, scripts), Minecraft Marketplace, Fortnite UGC mode, and similar surfaces where the user-distributed asset includes executable behavior delivered directly to end-user runtimes.
  • Smart-TV application stores: Roku Channel Store, Samsung Tizen Apps, LG webOS apps, Apple TV App Store, Amazon Fire TV apps, and the partner channels on console application stores that distribute applications running inside Client Runtimes. Plugins literally run as CSR. A browser extension executes JavaScript in the browser's Client Runtime alongside the host page. A VS Code extension executes JavaScript in the editor's runtime. An Office add-in executes JavaScript in the productivity tool's runtime. A Blender plugin executes Python in Blender's scripting runtime. A Roblox experience or a Steam Workshop mod executes runtime-interpretable behavior inside the platform's interactive runtime. The host application offered the plugin or extension a privileged seat at execution, and whatever the marketplace published takes that seat.

Privileges the seat carries are operational, not theoretical. Browser extensions can read every page the user visits and inject content into them. VS Code extensions can access workspace files, execute arbitrary code in the developer's environment, and read whatever credentials live in the editor's context. Office add-ins can interact with documents, including the document the user has open. IDE extensions reach the developer's source tree, build configuration, and any tokens cached for source-control or deployment authentication. Game-platform UGC assets reach the runtime's input, network, and persistence APIs. Runtime Anarchy applies here at marketplace scale. Every installed plugin inherits the host application's permissions, and a publisher compromise reaches every install with those permissions intact.

Plugin-Marketplace Publisher Compromise stands as a confirmed event category, alongside the established CDN and third-party-script categories. The marketplace surface is no longer a peripheral case folded into "browser extensions." It is its own route from open-source compromise to executing rendering-surface code, and a high-leverage one because it skips the build step entirely.

9.6: No Verification at the Client Runtime Boundary

Open-source supply-chain defenses are valuable. Signed packages keep published packages traceable to their publishers. Registry security closes the credential-takeover route into the most-used registries. Software bills of materials produce a manifest-level inventory of what an application asked for. Dependency-scanning tools surface known vulnerabilities in declared packages. Vulnerability databases (CVE, GHSA, OSV, ecosystem-specific advisories) carry the public record of known-bad versions. These controls reduce the attack surface meaningfully.

Every one of those controls operates upstream of the build. Those controls end where the bundle leaves the build. The Client Runtime Boundary, where the bundle arrives and execution begins, is where the upstream regime stops. At that boundary the runtime accepts the bundle, accepts whatever the bundle loads at runtime through the Manifest Illusion, and grants the loaded code the host application's permissions under Runtime Anarchy. None of the upstream controls reach inside that sequence.

Defenses needed at the Client Runtime Boundary do not exist as default capabilities of any major host runtime. A single-source-of-truth inventory of the runtime resources actually loaded would let the runtime compare what it just executed against what it expected to execute. Content-swap detection at runtime would flag a fetched file that did not match what the application owner intended. In-memory anti-manipulation would defend the executing code from runtime tampering by code that has already been admitted. None of these is a default capability in browsers, mobile-app runtimes, desktop shells, vehicle infotainment systems, IoT or OT dashboards, AR/VR runtimes, productivity-tool extension hosts, or game and user-generated-content interactive runtimes. The defensive primitives that exist (Subresource Integrity in the browser, code-signing checks at app-store load, sandboxing where it applies) are partial and platform-bound.

Malice Without Malware applies in its open-source-specific form. The same gap appears across the language, provider, and AI dimensions, each from a different angle. What they share is the Integrity Blindspot at the load-to-execute boundary. The flaw is architectural and endemic to the pattern, so it appears on its own in every runtime built this way. Open-source supply-chain defenses are necessary and worth deploying. They stop at the Client Runtime Boundary, where the bundle becomes executing code.