Third-Party Script Loading: The Direct Trust Problem
A third-party script tag hands a decision to someone else and never takes it back: which code runs at that address is the vendor's call, not the application owner's. The application owner places the tag; the vendor places the code at the URL the tag points to; the runtime fetches whatever sits at the URL on every load and executes it with the same permissions the user granted to the host application. The vendor controls what sits at that address and can change it between one fetch and the next. By writing that one line, the application owner has put the vendor inside the trust boundary: the vendor's code runs with the host application's full privileges and can change what the runtime does and what the user sees.
In browsers the mechanism is script tags loading vendor JavaScript URLs. That is the most visible case, not the boundary. Mobile WebViews load vendor scripts and SDKs into the host application's runtime, with the host's permissions. Hybrid mobile frameworks pull vendor JavaScript modules at runtime through their own loading mechanisms. Desktop shells that wrap a web runtime (Electron, Tauri) load third-party JavaScript and Node modules into the desktop runtime, with the desktop application's privileges. Productivity-tool extension hosts load extension code that inherits the productivity tool's data access. Vehicle infotainment runtimes, IoT and operational technology (industrial control) dashboards, AR/VR runtimes, and user-generated-content interactive runtimes each carry their own runtime-script-loading mechanisms. The trust dynamics are the same across all of them: the vendor delivers the code, the host runtime executes it, the host's permissions extend.
Two consequences follow from this delegation, and the broader supply-chain literature does not address either. The first is that most organizations cannot enumerate the third-party scripts their applications load at runtime. No amount of operational discipline closes it. The second is that loaded scripts inherit the host application's permissions wholesale: same DOM and storage, same network endpoints, same user-granted device APIs. The runtime draws no privilege boundary between first-party and third-party code at the moment of execution.
8.1: Script Loading as Runtime Delegation
Every loaded script follows the same path: the runtime resolves the URL, fetches the response, and executes it as code. The directive varies across Client Runtimes (script tag, WebView load API, native module loader, extension manifest); the fetch-and-execute structure does not.
Runtime-loaded scripts are not statically-linked libraries. A statically-linked library is fixed at build time. Its behavior travels with the file the application owner ships; if the library is malicious, that file carries the malicious code, and the application owner can open it and look. A runtime-loaded third-party script does whatever the code sitting at that URL does on the day it is fetched, and the application owner has no way to inspect that code before it runs.
A typical e-commerce site, news site, or SaaS web application loads dozens to hundreds of distinct third-party script sources at runtime. A typical mobile application carrying hybrid frameworks and analytics SDKs loads tens of script sources. A productivity-tool environment loads a script population that grows with each extension the user installs. Each source is a Placement and Access (P&A) position the vendor holds at runtime. Every one of those sources carries both problems: the application owner cannot list them all, and the runtime places no limits on any of them once they execute.
8.2: The Third-Party Script Inventory Problem
In production, no one can produce a complete list of the scripts a runtime loads. The problem is widely recognized; better operations have not closed it. Four structural reasons hold the gap open.
Transitive script loading. Scripts load other scripts. A tag manager, the hosted console a marketing team uses to decide which scripts a page pulls in, loads analytics scripts; analytics scripts load advertising scripts; advertising scripts load attribution scripts. The one script the application owner wrote into the page is a small fraction of what ends up running.
Dynamic script behavior. The script loaded today can load different content tomorrow without any change the application owner sees. The URL is constant; the code at the URL is not.
Tag manager dynamics. Tag managers add and remove scripts dynamically based on configuration changes outside the application's release process. A marketing team's change to a tag-manager rule alters the runtime script population without touching the application code.
Vendor SDK transitive dependencies. A vendor SDK loaded as a single script can pull in dozens of additional scripts as its own dependencies. The application owner sees one inclusion; the runtime executes many.
All four reasons follow the loading pattern onto every platform. A mobile WebView running a tag manager and several analytics SDKs faces the same transitive, dynamic, and dependency-driven population it cannot enumerate. An Electron shell with multiple npm-loaded modules presents the same. A productivity-tool environment with several installed extensions presents the same. The platforms differ; the inventory problem does not.
Better operations close pieces of the gap, never the whole of it. Better tooling, better vendor governance, and better tag-manager hygiene cut into the population without enumerating it. The runtime executes a population of scripts the application owner cannot enumerate, even with full inspection authority over the source code. The problem is structural.
8.3: High-Trust Script Categories
High-trust script categories operate at elevated privilege by design. Their function requires it.
- Analytics scripts (Google Analytics, Mixpanel, Segment, mobile analytics SDKs): read navigation, interactions, and often form contents.
- Advertising scripts: inject content and modify display.
- Payment scripts: handle financial information directly.
- Identity scripts: manage authentication, session establishment, and credentials.
- Trust and engagement widgets (chat, comments, captcha, document signing): hold privileged DOM and runtime access.
- Mobile attribution and tracking SDKs: reach device APIs.
- Productivity-tool extensions: reach user documents and data. Elevated trust is granted by necessity. An analytics script that cannot read interactions has no analytics function; a payment script that cannot handle financial information has no payment function; an identity script that cannot manage credentials has no identity function. Whoever compromises one of these scripts gets that same elevated access, for the same reason the script was given it. What makes a high-trust script useful is what its compromise gives the adversary.
8.4: Runtime Anarchy
Every control that exists here acts at the point content arrives: CSP governs what may load and execute, SRI checks the integrity of what is fetched, and CORS governs whether running code may read what a cross-origin response returned. Once a script clears that gate and executes, nothing governs what it may do. Within a single execution context every script is co-equal, with full rights to read and modify shared state, the DOM, globals, and other scripts' data. There is no per-script sandbox, no privilege hierarchy, and no authority imposing limits; the only real interior boundaries are coarse and document-level (cross-origin iframes, sandboxed frames, workers), not per-script. That is Runtime Anarchy: CORS and CSP enforce rules on who is allowed through the door but once they are in the room, there are no rules. A script that reaches this context reaches every privilege the host application holds: the same DOM and UI access; the same cookies, localStorage, IndexedDB, and equivalent storage; the same network endpoints; the same camera, microphone, geolocation, and payment APIs where granted or invoked; the same sensor and actuator APIs in vehicle, AR/VR, IoT, and OT contexts; and the same document and data access in productivity-tool extension contexts. The third-party receives the host's permissions wholesale, by design.
Loaded scripts are not isolated. A subprocess runs in its own address space; a sandboxed component runs under a constrained capability set; an out-of-process service runs at a network boundary. A third-party script runs inside the host's runtime, with the host's permissions, in the same privilege space first-party code occupies. Third-party script compromise equals full application compromise from the user's perspective.
Real compromises show what that inheritance buys an adversary. A compromised analytics script can exfiltrate payment data. A compromised payment script can capture identity credentials. A compromised mobile attribution SDK can access device APIs the host application was granted. A compromised productivity-tool extension can reach the user's documents and data. The runtime does not know the script is acting beyond its declared purpose. The runtime does not have a model of declared purpose.
The same inheritance applies to everything else the runtime fetches and trusts. A compromised CDN-delivered library inherits the application's trust. A compromised inference response, the answer that comes back when the application calls a model, inherits the application's authority to act on it. A compromised plugin inherits the host application's privileges. A compromised data endpoint inherits the application's trust. A compromised over-the-air bundle, code an installed app pulls straight from a server without going back through the app store, inherits the host application's permissions. As long as a runtime accepts content because of where it came from, and then runs that content with the host's permissions, whoever compromises the source gets the host's permissions too.
Supply Chain Injection is how content enters. The Runtime Injection Advantage is why an adversary would rather act inside the runtime than anywhere earlier in the chain. Runtime Anarchy is what the runtime gives the adversary once content has entered: co-equal execution with the host's full permissions. Combined, they are the full ATG attack architecture.
8.5: Scale of Exposure Across Application Categories
Exposure varies sharply by application category. E-commerce typically carries the highest third-party script populations, often dozens to over a hundred sources per page. News and media sites are heavy, driven by advertising, analytics, and engagement widgets. SaaS and productivity surfaces are moderate. Banking surfaces are lower on public pages and higher inside authenticated experiences. Government public-facing surfaces span thousands of sites, comparable in scope to large enterprise, with per-page populations generally lower than commercial peers.
Authentication does not change the runtime architecture. Tens of thousands of authenticated portals sit beyond the public-facing front: government and agency portals, first-responder web portals, the web-based tools governments procure from their vendors and the Defense Industrial Base, secure banking portals, and stock-trading platforms. All are Client Runtimes that load third-party scripts in the same way public surfaces do. Login walls, network isolation, and procurement controls reduce the audience, not the architecture. The inventory and inheritance dynamics are the same.
Specialized Client Runtimes change the consequence calculus. Vehicle infotainment, IoT and OT dashboards, and AR/VR runtimes carry smaller per-application script populations than browsers or mobile, but the consequence per compromised script is disproportionate. A compromised script reaching a vehicle infotainment runtime, an industrial control dashboard, or an AR/VR sensor stream can produce physical-world effects browser-based exposure does not.
Counting the scripts changes how large the problem looks; it does not change how the runtime treats them. Every loaded script is a placement and access position. Every loaded script inherits the host's permissions.