Mid Term: Months Three to Twelve
What you ship is not a finished application. It is instructions the user's own device follows to put the interface together as it renders, from parts you do not control and cannot inspect at the moment they arrive. The first ninety days governed those parts without touching how they get put together. These months change how it gets built.
Build less of the interface on the client. Govern the pipeline that delivers what does get built. Extend the browser's controls to every other surface where something renders for a person. Find out in depth who each remaining supplier actually is. And detect what can be detected while rehearsing for what cannot.
Reducing Client-Side Composition
Your exposure scales with how much of an interface gets built on the user's device out of parts fetched from elsewhere. Building it there has permanent economics: pushing rendering and computation onto the user's own hardware is what made the approach worth adopting, and it is why nobody is giving it up. How much any one interface leans on it is still a choice you make per interface, and the highest-stakes ones should lean on it least.
Assemble the content on infrastructure you control and deliver it finished. For a browser-hosted interface that can bear the user-experience trade-off, server-side rendering is the strongest defense available today. Your users' devices stop doing that assembly for that content, the gap between what your application declares and what it actually loads largely closes, and code writing more code on the client largely disappears. Two limits keep it partial. Applications described as server-rendered usually hydrate, meaning the client attaches behavior to the delivered HTML and takes over from there, loading further scripts and pulling in third-party content, which brings the exposure back in proportion to how much the client resumes doing. Pure server-side rendering with no client-side scripting is the strongest form, and few real applications meet that bar. The server-side build has its own supply chain too. For a transaction approval screen or an operator console, moving the work is still worth its engineering cost.
Fetch analytics, fonts and libraries, review them, version them, and serve them from origins you operate, so your users load only from addresses you control. That generalizes the self-hosting decision from the first ninety days to every third-party resource you can put behind your own origin. A change upstream then has to pass an inspection point on its way to the Glass instead of arriving directly. The limit is the one self-hosting carries: proxying governs the delivery path, not the data endpoints your proxied code still calls at run time.
For resources that have to stay third-party, use sandboxed iframes, workers and permissions policies to limit what each one can reach inside the page. Browsers enforce those boundaries today. Most sites simply never set them. What they push back against is that once you let code in, it runs with your application's full rights, and nothing in the policy that admitted it has anything further to say about privileged-API access, DOM manipulation, storage access, or what it loads next. Containment does not repeal that. It narrows the rights admitted code inherits, and narrowing is what is available.
Serve live prices, control forms and transaction confirmations from a separate, locked-down origin inside a cross-origin iframe. An iframe boundary works in both directions, and this puts your own content on the protected side of it. The same-origin policy then stops every script in the host page, including the dozens of third-party ones, from reading or rewriting what is inside that frame. Payment providers already use this pattern to keep card fields out of reach of the merchant page, and it transfers directly to any content whose integrity matters more than the page around it. Two conditions keep it real. The isolated origin has to stay clean, carrying no third-party code, or you gave the protection away at the door. And the boundary protects the inside of the frame, not the page around it: a compromised host page can still hide, overlay, resize or replace the whole frame with a lookalike. Pair it with frame-ancestors restrictions, and treat host-page integrity as the separate, still-open problem it is.
Give each critical application a named maximum number of third-party resources allowed to run in it, put an accountable engineer's name on that number, and review it whenever anyone proposes an addition. A budget turns reduction from a one-time cleanup into a standing constraint.
Your parts are secure and the plant that assembles them is not. Building less on the client, and putting prices, control forms and confirmations behind boundaries the browser enforces, shrinks the plant. That is this horizon's answer to an application that ships as instructions and gets built on somebody else's device.
Dependency Pipeline Controls
Most of what runs in a client runtime is open-source dependency code, and contributing to or taking over a package is the quietest route onto the Glass. The pipeline that pulls that code into your builds is a control surface in its own right.
Build from an internal package source holding reviewed, pinned versions rather than pulling from the public registry at build time. A private registry or curated mirror stops the public ecosystem's churn at its own front door, and adopting anything new becomes a decision instead of a side effect.
Verify provenance attestations at that front door, and treat any critical package you cannot verify as a finding. Major registries now ship them: a signed record of how a package was built and by whom, confirming that a package came from the repository it claims, built by the workflow it claims. The limit is worth stating: provenance confirms where a package came from, not what it does. A maintainer who turns adversary ships perfectly attested compromise. Provenance closes off impersonation, not takeover.
Let new dependencies into the mirror through a human decision informed by maintainer history, ownership, release cadence and install-time behavior. That review is where somebody looks for takeover directly, and the reason it matters is what happens afterward: once packages compile into a bundle, the bundle is what executes but it carries no record of where its parts came from, so code from many sources arrives at the runtime under your own origin, indistinguishable from your own code and from each other. What gets into the bundle deserves scrutiny in proportion to how invisible it becomes once it is there.
Alert on maintainer changes, ownership and publisher transfers, yanked or replaced versions, and unusual release patterns across the whole tree as they happen. Commercial and open-source dependency-monitoring services do this today. A point-in-time review ages fast: XZ Utils passed every review that mattered until control moved to a new maintainer after everyone stopped looking, and somebody found it by accident rather than by process.
Compare each release's dependency tree against the last, and treat a new transitive dependency as what it is: a new party with code in your product, as visible and as reviewable as a code change.
A governed pipeline does not make your dependencies trustworthy. It makes every change to them visible, reviewable and attributable, which is the control available over code nobody on your payroll wrote.
The Glass Beyond the Browser
The Glass is any surface where something renders for a person, and the browser is only the most familiar. The same build-at-run-time pattern runs in mobile application runtimes and the webviews inside them, in desktop shells built on embedded browser engines, in smart-TV applications, in kiosks and digital signage, in point-of-sale terminals, in vehicle infotainment, in industrial control and SCADA operator screens, in AR and VR scene engines, and in the plugin hosts of productivity tools.
Each of those runtimes inherits the pattern from a shared design rather than catching it from the others: content composed at render time, executed on the Glass. Nothing spreads between runtimes, and nothing gets eradicated by treating cases one at a time, because a patch to any single runtime does not reach the design that produces the condition.
Your defenses are uneven across those surfaces, and the plan has to account for that. CSP, SRI, Trusted Types, the Permissions API and the rest are browser-engine capabilities, and your application still has to switch each one on. Everything else that hosts a client runtime offers equivalents ranging from partial to absent, and they thin out on exactly the surfaces where the consequences are highest. Over-the-air bundle delivery, where code updates arrive straight from a server after install without going back through the app store, has no equivalent of a runtime integrity check. Hybrid runtimes have nothing like CSP for the bridge that lets web code call native device functions. Desktop shells and development-environment plugin hosts carry no consistent equivalent, and a loaded plugin runs with the host application's permissions. Where a host embeds a browser engine, that engine's primitives are available inside the embedded surface whether or not the host configures them, and some vendors say so in their own documentation. What no host outside the browser gives you is a default, and availability is not deployment.
So transfer what you already know how to do. Inventory the embedded runtimes you operate, recording what each one loads at run time and from where. Apply the browser-grade disciplines wherever the platform supports them, including inside embedded browser surfaces where the primitives exist but nobody ever switched them on: pinned content, constrained load sources, first-party serving. And for fixed-function displays, add the control a browser cannot have. A signage player or an operator console needs a short, known list of endpoints, enforced at the network layer, with an alert on anything outside it. A general-purpose browser cannot carry an egress allowlist. A device that renders one dashboard can, and should.
Weigh isolated networks accurately rather than exempting them. Isolation does not remove Attack the Glass. It relocates the supply chain, because every component crossed the boundary at some point and carried its exposure in with it. Well-run industrial control environments compensate with perimeter measures, URL pinning, mutual TLS, network segmentation and hardened runtime engines, all of which materially narrow the script environment compared with a commercial deployment. None of those reach the supply-chain source of the rendering-layer components, which is where Attack the Glass sits. The supply chain inside a protected network is nonetheless smaller and more controlled than the public internet, which is exactly why inventory and pinning pay off fastest there. Put that difference in the plan, and do not let it become a sense of immunity.
Your least browser-like screens are usually your most consequential and your least defended. Transferring the browser's discipline to them is unglamorous work with a high return, and it is bounded by the same fact that motivates it: the patterns translate across runtimes, and the code that implements them does not.
Supplier Diligence: Ownership, Operator, and Jurisdiction
Every third-party resource that survives reduction belongs to somebody, and vendor risk management is where you find out who. Free components are not outside this. Many technologies offered free exist to establish Placement and Access, a standing right to execute inside your runtime, and an analytics snippet or an open-source component grants that whether or not money changed hands. Govern the free ones exactly like the paid ones, and remember that what a free component established can change owners along with the component.
A questionnaire is not diligence. For every provider whose code or content reaches the Glass, establish six things. Where the technology originates: who wrote it, where it is developed, who maintains it now. The full operational footprint: the data centers, networks and staff locations actually serving you, not the headquarters on the letterhead. The data flows: what leaves your runtime through their code, where it lands, who can read it. The sub-processors: the enumerated parties behind the name on your contract, because the ones that matter are often two or three contracts removed from the signature. Ownership and control: who operates the infrastructure, not only who brands or finances it. And the insider surface: who inside that provider holds administrative control of what reaches you.
Scope the exercise honestly, because the public record it draws on is thinner here than in any comparable industry. For physical assets a land registry says who holds title, securities filings say who controls a listed company, and threshold reporting leaves a trail when large sums move. Nothing equivalent covers the infrastructure that delivers code to a screen. A company registry names an owner. Nothing names the operator, and nothing files a report when a CDN is sold, a package is handed to a new maintainer, or a publisher account is transferred. So diligence here is mostly the provider's own answers, tested for consistency and re-tested on a cycle, and your assessment should say so rather than implying a verification it cannot perform.
An investor with a minority stake in a delivery provider has influence over a company. Whoever operates the network, runs the servers and holds administrative control of the paths the bytes travel has the delivery path itself, and can shape what renders without asking anyone. Assessments confuse the two more often than they confuse anything else. Legal ownership and operational control are routinely not the same people: whoever holds commit access, publishing credentials, authority over runtime configuration or platform-administrator rights can be replaced without anyone outside being told. When both appear in one supply chain, the operator is the sharper risk, and your assessment should say so.
Assess the insider surface just as concretely. Publish rights to the package, signing keys, deploy access to the serving infrastructure. Somebody can gain that access by recruiting or pressuring one person on the inside, and a provider who cannot tell you how many people hold those keys has answered the question in the way that matters.
Map jurisdiction and governing law before you need them. Where the vendor is incorporated, where its operations and infrastructure actually sit, and which law governs the contract decide whether you can enforce the notice, audit and remedy clauses you negotiated at all. If the map says you cannot enforce a clause, do not count it as a control. Jurisdiction also decides which governments can lawfully compel the provider, which bears directly on who could one day be serving your users.
Then write what you learned into the contract. Notification of change of control. Notification of material changes to served content and to the sub-processor list. Audit rights. These terms are ordinary to negotiate and meaningful to hold, provided the jurisdictional map says they can be enforced. They are also the only instrument that turns an unannounced change of owner into a notified one for the providers you contract with, which makes that the highest-value clause in the set.
Finally, score suppliers on what they could do rather than on what kind of company they are. Scope of effect, persistence, pre-operational intelligence required, attribution difficulty, reversibility, resource investment, time horizon, detection difficulty. The useful question about a supplier is what whoever controls it could do, how widely, for how long, and how you would find out. That follows from the access they hold, not from the size or the flag of the company holding it.
Diligence does not remove a supplier from your interface. It replaces an unknown owner with a named one, a mapped jurisdiction and an enforceable contract, which is the difference between trusting a supplier and merely depending on one.
Client-Side Monitoring and Rendering Integrity Checks
Detect systematically what can be detected.
Deploy script monitoring on the interfaces that warrant it, and state its coverage plainly: it watches the pages and the vantage points you point it at, with the permissions you granted it. The commercial script-monitoring and client-side protection category that grew up around PCI DSS 4.0 inventories scripts, alerts on change, and detects classes of tampering on designated pages. It covers pages an observer can watch, and that is the whole of its reach.
Then turn the ad hoc vantage-point comparison of the first ninety days into a scheduled program. Fetch and fully render your high-stakes interfaces from multiple geographies, networks, device profiles and browser engines on a fixed cadence. Capture the served resources and the rendered DOM. Compare against a known-good baseline and against each other, and alert on drift rather than reviewing by hand. Synthetic-monitoring and headless-browser tooling supports every step today. What this catches that single-point monitoring cannot is divergence: one address returning different things to different people.
Conditional delivery decides what a resource returns based on who is asking, using the same conditions any content-personalization system already uses: source address and inferred geography, device and user-agent characteristics, time of day and session timing, who is signed in, what they did before, which group they were put in, and which experiment bucket they landed in. You detect a swap exactly to the extent that your vantage points differ along the condition somebody used. Geography and device profile are cheap to vary, so region-scoped and device-scoped substitution is genuinely within reach. Who is signed in, what they did before and which group they belong to are not properties a synthetic observer has, so a swap conditioned on those reaches those users and nobody you operate, whether that group is a hundred thousand people or one named individual on one device. Build your vantage points to vary along the conditions that can be varied, say plainly which ones they cannot express, and treat that list as a stated blind spot rather than a footnote.
Absorb the substitution scenario into incident response, and absorb the missing evidence with it. A substituted resource lives in memory for one session and is gone when the tab or the application closes. A network monitor records metadata, timing, size and destination, never the content. Whoever serves a resource also decides whether the client keeps it, so it can be served once, marked no-store, and leave the cache an investigator would search entirely clean. Write a runbook for the day somebody finds a served resource or a rendered page altered, and start it with capture: how client-side evidence gets preserved before it vanishes, who cuts off the supplier, who notifies affected users, who calls the provider. Then rehearse it. A tabletop built on a false operational reading, an altered payment flow or a targeted executive deception, run with the people who would actually take the call, is the difference between a procedure on paper and one that survives contact. The out-of-band verification from the first ninety days is only real if it holds up in that rehearsal.
Track four numbers so the year can be reviewed. How many third-party resources each interface loads, trending down, with a name attached to every increase. What share of high-stakes interfaces serve pinned or first-party resources. What share run an enforced CSP and monitoring. What share have verification procedures in place. Where those numbers show gaps, state the gaps plainly, because they are what the long-term roadmap picks up.
You can detect a swap served to a whole region, network or device class, with tooling that exists today, and it is worth running. It limits how widely a substitution can spread before somebody notices, along the conditions you can vary. It will not catch a swap aimed at who the recipient is, and nothing deployed today will.
What Carries Forward
By the end of the year less of the interface is built on the client, your prices and confirmations sit behind boundaries the browser enforces, every change to the dependency pipeline is visible and attributable, browser-grade discipline reaches the surfaces that are not browsers, your remaining suppliers are named and contractually bound and mapped to a jurisdiction, and detection runs across every condition you can actually vary.
Every one of these has an end date. Dependency counts drift upward once no budget holds them down, diligence findings age as providers change owners, and procedures decay without rehearsal. Keeping what you gained is what the long term takes up.