Infrastructure Review Stack

HTML and CSS Sandboxes for Isolated Web Code Execution

Layered isolation strategies contain threats that browser sandboxing alone cannot prevent.

· 8 min read
Cover illustration for “HTML and CSS Sandboxes for Isolated Web Code Execution”
Code Execution Sandboxes Compared · October 28, 2026 · 8 min read · 1,853 words

HTML and CSS sandboxes make untrusted web code safer to execute by enforcing boundaries at several layers. No single boundary covers every threat. Sound architecture depends on understanding what each layer contains, what it leaves exposed, and how persistent sessions and deployment requirements change the risks.

Why executing untrusted web content requires more than good intentions

An agent that browses a page and then executes a shell command connects untrusted content to real permissions. Early LLM deployments largely returned text, but ReAct and tool-use architectures let agents call APIs, control browsers, and run interpreters. Code review alone cannot govern actions composed dynamically from content encountered during execution.

Ambient authority lets an agent process inherit database credentials, network access, and filesystem permissions beyond what any one operation needs. If malicious content persuades that agent to use its legitimate permissions destructively, it becomes a confused deputy. Traditional role-based access control validates identity, so an action with malicious intent can still be authorized and serve an attacker.

Nor does damage require an attacker. Faulty agent logic can recursively delete a critical directory, while an unverified SQL statement can drop tables. Better prompts do not remove the permissions that make these failures possible. Sandboxing instead restricts the environment in which actions occur, containing their consequences without first having to classify every input correctly. The architectural objective is to limit the blast radius.

The attack patterns that browser-level isolation was not built to stop

Browser sandboxing separates the privileged browser process from renderers executing web content. Multi-process separation, restricted system calls, and security checks at inter-process communication boundaries constrain access to the host. Chromium combines OS-level sandboxing with site-based isolation, while Firefox implements site isolation through Fission and Safari uses WebKit2’s split-process model.

The boundary is concrete, but its purpose is limited. Chromium uses Mojo IPC and Firefox uses IPDL for communication between processes, with policy enforced at their interfaces. WebAssembly adds another local boundary with isolated linear memory that has no direct access to the DOM or JavaScript heap. None of these controls can decide whether an instruction on a page should become an agent’s next task.

What happens when the browser behaves exactly as designed? Brave’s research demonstrated “unseeable prompt injections” that hide instructions from human viewers while leaving them readable by an LLM. White-on-white text or a zero-pixel CSS class can deliver instructions without exploiting a renderer. An agent could then use its own permissions to exfiltrate payment data encountered while navigating an e-commerce site.

This creates four attack patterns beyond process escape. Tool poisoning introduces malicious behavior through MCP servers, while prompt injection can lead to filesystem access and SSH key exfiltration. Compromised MCP tool discovery can capture credentials. A compromised agent can also move laterally into internal microservices with service mesh credentials it has inherited.

How the four dominant isolation technologies create different boundaries at different layers

Containers place boundaries around processes using Linux namespaces, including PID, network, mount, IPC, and user namespaces. Cgroups limit resources, and seccomp filters system calls. Their overhead is low, but their kernel is shared. A successful host-kernel exploit can therefore threaten other workloads on the same host, so ordinary containers alone are not enough for fully untrusted runtime code.

MicroVMs move the boundary beneath a workload’s kernel. Firecracker and Kata Containers give workloads dedicated kernels with hardware-enforced isolation, so exploiting a guest kernel does not by itself provide host-kernel access. They offer stronger separation but have the longest cold starts among these approaches. “Use a container” and “use a microVM” thus answer different questions about which component may be compromised.

V8 isolates and WebAssembly work at the runtime layer. Each V8 isolate has its own heap and global scope and cannot access another isolate’s memory, but it can run only JavaScript and TypeScript. WebAssembly has memory-safe execution and a deny-by-default capability model, and it can run code from multiple languages. WASI and the Component Model extend its use beyond the browser into server-side execution.

These runtime approaches start fastest but serve narrower execution needs. Meanwhile, gVisor sits between containers and microVMs in isolation strength and startup cost. The choice is not simply speed against security, because the technologies constrain different interfaces. For agent workloads that alternate between idle intervals and short execution bursts, low overhead is attractive, but it does not eliminate a shared kernel’s attack surface.

What layered isolation actually looks like for HTML and CSS execution in practice

A layered web sandbox places browser-level isolation inside a microVM or hardened container boundary. Site isolation separates cross-origin content, while a microVM adds a dedicated guest kernel between the browser workload and the host. This arrangement limits the consequences of a renderer exploit or a prompt injection that reaches shell execution without treating either layer as infallible.

Deno Sandbox launched in beta on February 3, 2026, with each sandbox running in a dedicated Firecracker microVM on Deno Deploy infrastructure. CodeSandbox, now part of Together AI, provides its SDK for provisioning, cloning, and restoring isolated environments through microVM infrastructure designed for thousands of concurrent VMs. Google Agent Sandbox on GKE uses the Agentic Sandbox Python client to deploy a sandboxed Python developer environment on a Google Kubernetes Engine cluster.

CSS has historically revealed visited links through :visited style queries and later timing side-channels, although modern browsers have substantially mitigated these attacks. Attribute selectors can also probe DOM state. These behaviors take place above the operating-system boundary, so they need renderer-level controls and Content Security Policy even with stronger VM separation.

CSP restricts which scripts, styles, and resources a renderer may load and execute, reducing the attack surface for XSS. It serves a different purpose from kernel isolation. The layers assume that components within their protection may fail, with browser isolation containing a compromised renderer and microVM isolation containing a compromised browser. Network egress filtering adds another boundary in case the VM itself is compromised.

Where the isolation boundaries break down: the cases engineers need to know

Semantic attacks expose the sharpest limit of process isolation. Running a page safely does not let a sandbox tell a legitimate instruction from malicious page text. Zero-pixel divs, white-on-white text, and comment-embedded instructions can remain legible to an LLM while rendering innocuously to a person. The injection succeeds through the agent’s interpretation.

A VM permitted arbitrary outbound requests can still exfiltrate accessible data, contact internal services, or download additional payloads. Isolation does not imply restricted connectivity. Similarly, a malicious MCP server can return credential-capturing payloads during tool discovery, and the invoked tool can operate with whatever permissions exist inside the sandbox.

Prompt injection calls for output validation and agent-level guardrails, while MCP poisoning calls for tool signature verification before invocation. Package allowlisting or pre-built snapshot environments reduce supply-chain exposure. Explicit egress controls constrain network misuse, supported by non-root containers, read-only mounts, and strict timeouts. In shared managed environments, teams also need to check the tenancy model because internal isolation alone does not rule out cross-tenant exposure.

How statefulness changes the security calculus for long-running web agent sessions

A multi-turn web agent accumulates packages, files, configuration changes, and intermediate outputs. Destroying its sandbox after every turn discards useful context and repeats setup work. Preserving it creates a different security problem. Earlier filesystem writes and installed dependencies remain available to later turns, so a compromise can persist even when the next page or instruction is benign.

Four lifecycle patterns make this trade-off explicit. Fresh ephemeral sandboxes serve one task and disappear on completion. Persistent paused sandboxes preserve filesystem and memory snapshots between runs for fast resumption. Snapshot/fork environments branch copy-on-write images from a parent that already has its dependencies installed, while long-running indefinite sandboxes stay alive for the whole multi-day task.

CodeSandbox’s SDK supports continuous context through snapshots that resume development after inactivity. Its forking mechanisms also let agents branch from a common base for A/B testing of behavior. Persistence is useful, but it preserves risk too. Snapshot cleanliness and the choice of parent state become security decisions because a branch can retain the mutations present in its source.

Idle sessions also consume resources beyond active CPU time. Memory, guest and host page caches, and writable state may remain pinned, reducing cluster capacity. Snapshot capture and restore can cut waste, but frequent tool calls add overhead each time that cycle repeats. Make statefulness in a long-running container deliberate, with explicit controls for preserving, branching, cleaning, and destroying state.

What compliance and enterprise deployment requirements add to the sandbox architecture decision

Auditors can scrutinize cross-tenant data exposure even when a managed service uses strong isolation. Where the workload runs therefore affects architectural viability. Customer-managed compute in an organization’s own AWS, GCP, or Azure account keeps execution within its VPC and supports data residency requirements without depending solely on assurances about shared infrastructure.

Certification scope needs equally careful attention. SOC 2 Type 2 is a baseline enterprise expectation, HIPAA applies to healthcare deployments, and GDPR governs processing on behalf of EU residents. A vendor’s hosted-service certification may not cover a customer-managed deployment of the same product. Teams need to establish which deployment modes are covered before choosing an architecture for regulated workloads.

Operational compatibility can narrow the options further. Existing containerized workloads need custom image support if adoption is to avoid a full stack rewrite. Regulated environments also need observable, logged file writes, network requests, package installations, and shell commands. Strong isolation cannot replace that audit trail. Open-source infrastructure gives teams another way to build trust because they can inspect runtime behavior directly.

How to evaluate sandbox architecture for an HTML and CSS execution workload

Evaluation should begin with the source of the code. Is the workload running arbitrary pages and user-submitted HTML, or output that is partly trusted within a controlled pipeline? Fully untrusted content calls for a microVM base with browser process isolation, CSP, and egress filtering. Controlled pipelines may justify gVisor or hardened containers with defense in depth, although microVMs remain the safer default. Known internal developer code is the narrower case where containers with seccomp and namespace isolation may suffice.

Next, evaluate the session. Does each run start clean, or must an agent pick up its work across turns? Ephemeral sandboxes are simpler and safer, while multi-turn work requires explicit snapshot, fork, and teardown policies. Concurrency changes the operational trade-off too, because cold starts tolerated for occasional execution can become bottlenecks when thousands of sessions start together.

Teams need to settle network and deployment policies before they choose a provider. The recommended approach is to map legitimate outbound destinations and deny everything else by default. For regulated workloads, the evaluation should require customer-managed compute within the customer’s VPC and certification coverage for that deployment model. An architecture that fits the organization as well as the threat model needs custom images, auditability, and runtime transparency.

Finally, measure the full execution loop. That loop includes sandbox creation, workspace preparation, web-content execution, result collection, and cleanup. Purpose-built agent infrastructure can reduce the workarounds needed to add fast provisioning, deliberate statefulness, and explicit isolation guarantees to tools designed for trusted workloads. A fast cold start is useful only when the agent can begin meaningful work immediately afterward.

More in Code Execution Sandboxes Compared