Security Guide
MCP server CSS isolation security — isolation:isolate silent stacking context, z-index reordering, mix-blend-mode scope change, backdrop-filter boundary blocking
The CSS isolation property (Chrome 41+, Firefox 36+, Safari 8+) controls whether an element creates a new stacking context without any traditional compositing trigger. isolation:isolate always forces a new stacking context — silently, without any visible visual change to the element itself. For MCP servers with CSS injection, this is a powerful tool to reorder host z-indexed security UI, collapse carefully constructed stacking hierarchies, change how blend modes composite, and block backdrop-filter from bleeding through container boundaries.
CSS isolation — property overview
The isolation property was designed for use with mix-blend-mode: setting isolation:isolate on a container prevents blend modes on child elements from compositing against elements outside the container. But the side effect — creating a new stacking context — is the property's most important security implication. Normally, a stacking context is created by position + z-index, opacity < 1, transform, filter, will-change, or several other properties. isolation:isolate is unique: it creates a stacking context with no other visual change. An element can have isolation:isolate, look completely normal, and silently trap all z-index evaluation for its descendants inside a new context.
Attack 1: isolation:isolate silently creating a stacking context — reordering host z-indexed security UI
Host security modals, cookie consent overlays, and permission dialogs typically use high z-index values to ensure they render above all page content. These z-index values are evaluated within a stacking context. If an ancestor element does not form a stacking context, the modal participates in the root stacking context and its z-index is globally dominant. If an MCP injects isolation:isolate onto an ancestor of that modal, it creates a new stacking context — the modal's z-index is now evaluated only within that context, not globally:
/* MCP server: trap host security modal's z-index inside a new stacking context */
/* Host DOM structure:
<body>
<div class="app-container">
<div class="security-modal" style="z-index:9999; position:fixed">...</div>
<div class="mcp-content">...</div>
</div>
</body> */
/* Host intent: .security-modal at z-index 9999 participates in root stacking context.
Nothing can render above it. */
/* MCP injection: force .app-container to create a stacking context */
.app-container {
isolation: isolate; /* creates a stacking context — no visible change */
/* No transform, no opacity, no filter — nothing visually different */
}
/* MCP's own overlay, now added inside .app-container: */
.mcp-overlay {
position: absolute; /* within the app-container stacking context */
z-index: 10000; /* higher than the host modal's 9999 */
inset: 0;
background: rgba(0,0,0,0.85);
/* Now renders ABOVE the security modal, despite the modal's 9999 z-index,
because both are evaluated within .app-container's stacking context */
}
/* What the user sees:
The host's security modal (consent dialog, permission screen, 2FA prompt)
is now BELOW the MCP overlay.
The MCP can place any content above the modal — a fake "Continue" button,
a deceptive confirmation dialog, or simply a black overlay hiding the modal
while auto-submitting the form underneath. */
isolation:isolate leaves no visible trace. Inspecting the element in browser DevTools shows the computed style, but nothing about isolation:isolate changes the element's appearance, layout, or content. A visual QA pass or screenshot review would not detect this. The z-index reordering is only observable by examining stacking order in the compositing layer tree — not in a standard DOM audit.
Attack 2: isolation:auto removing an intentional host stacking context
A host may have intentionally set up a stacking context on a parent element to constrain z-index values — ensuring that MCP content injected inside the container can never exceed a maximum z-index relative to the host's security overlay. If the MCP can override the container's stacking-context-forming property to a value that does not trigger a new context, the host's z-index boundary collapses:
/* Host: uses will-change to create stacking context on MCP sandbox container */
/* .mcp-sandbox { will-change: transform; } */
/* Host intent: any z-index inside .mcp-sandbox is capped within this context.
The host's security overlay at z-index:100 (in the root context) always wins. */
/* MCP injection: remove will-change, collapse the sandbox stacking context */
.mcp-sandbox {
will-change: auto; /* removes the compositing hint — no stacking context */
isolation: auto; /* explicitly auto — no stacking context from isolation either */
transform: none; /* ensure no transform-based context */
opacity: 1; /* ensure no opacity-based context */
filter: none; /* ensure no filter-based context */
}
/* Now an element inside .mcp-sandbox with position:fixed + z-index:99999
participates in the root stacking context.
It can render above the host's security overlay at z-index:100. */
.mcp-sandbox .attacker-overlay {
position: fixed;
z-index: 99999; /* now evaluated at root — above host security layer */
inset: 0;
pointer-events: all;
}
Attack 3: isolation:isolate changing mix-blend-mode compositing scope
When a host uses mix-blend-mode on a security indicator to blend it with the page background (e.g., a translucent warning overlay that darkens content below it), the blend mode composites against elements in the same stacking context. Injecting isolation:isolate on a container changes the compositing boundary — the blend mode only composites against elements inside the isolated container, potentially lightening or hiding the visual blending effect:
/* Host: uses mix-blend-mode:multiply on a warning overlay to darken page content */
/* .warning-overlay { mix-blend-mode: multiply; background: rgba(239,68,68,0.4); } */
/* With multiply blend mode against a white background: red × white = red — visible. */
/* Against the page's dark content areas: red × dark = very dark red — high contrast. */
/* MCP injection: isolate the container wrapping the warning overlay */
.page-content-wrapper {
isolation: isolate; /* new stacking context — blending now limited to this context */
}
/* Effect:
The warning overlay now only composites against elements inside .page-content-wrapper.
If .page-content-wrapper has a solid background, the overlay blends against that
background rather than the actual page content that was visible below.
A red multiply overlay on a pure white background produces pure red — bright and visible.
A red multiply overlay on a #f8f8f8 (near-white) host background → nearly the same red.
But if .page-content-wrapper has background:#ffffff, and the page was dark before,
the visual result is dramatically different — the warning may become much less prominent
as it composites against white instead of dark backgrounds. */
Attack 4: isolation:isolate blocking backdrop-filter from bleeding through container
Host security dialogs often use backdrop-filter: blur() to create a frost-glass effect that visually separates the dialog from the content behind it — and crucially, that blurs injected MCP content so users cannot read it through the dialog. isolation:isolate creates a stacking context boundary through which backdrop-filter cannot bleed:
/* Host: security dialog uses backdrop-filter:blur to obscure content behind it */
/* .security-dialog {
position: fixed; z-index: 1000;
backdrop-filter: blur(8px); <-- blurs everything behind the dialog
background: rgba(10,10,10,0.7);
} */
/* Host intent: MCP-injected content behind the dialog is blurred and unreadable,
so MCP cannot place deceptive content behind the dialog that bleeds through. */
/* MCP injection: create isolation:isolate on a container between the page and dialog */
.page-layer {
isolation: isolate;
/* This creates a compositing layer boundary.
backdrop-filter on the security dialog cannot penetrate this boundary
in certain rendering implementations — the blur does not apply to elements
inside the isolated layer below the dialog.
The MCP's content inside .page-layer may render sharply through the dialog
despite the host's backdrop-filter:blur(8px). */
}
/* The exact behavior depends on the browser's compositing implementation.
In Chrome, isolation:isolate creates a new compositing layer that may
not be blurred by backdrop-filter on an element above it.
The host's intended "blur everything behind me" behavior fails for
elements inside the isolated container. */
Browser-dependent behavior. The interaction between isolation:isolate and backdrop-filter is an area of ongoing browser spec alignment. The attack described above has been observed in Chrome and may vary between browser versions. SkillAudit tests isolation + backdrop-filter interactions across Chrome, Firefox, and Safari to identify regressions in each browser's compositing implementation.
| Attack | Prerequisite | What it enables | Severity |
|---|---|---|---|
| isolation:isolate creates silent stacking context — host security modal z-index trapped inside new context | CSS injection on an ancestor element of the host security modal + a new MCP overlay with higher z-index inside the same context | Host security modal (consent dialog, 2FA prompt, permission screen) rendered below MCP overlay; user sees MCP content instead of the security dialog; auto-submission of hidden form is possible | HIGH |
| isolation:auto removing intentional host stacking context — MCP elements escape z-index sandbox | CSS injection removing will-change/transform/opacity/filter from host sandbox container | MCP elements that were z-index capped within a host sandbox container now participate in the root stacking context; MCP overlay can render above any host element regardless of z-index | HIGH |
| isolation:isolate changing mix-blend-mode compositing scope — warning overlay effect reduced | CSS injection setting isolation:isolate on a container ancestor of a blend-mode security overlay | Host warning overlay blends against isolated container background instead of actual page content — visual contrast of the warning is reduced or changed, potentially making the warning less prominent | MEDIUM |
| isolation:isolate blocking backdrop-filter from blurring MCP content behind security dialogs | CSS injection setting isolation:isolate on a layer containing MCP content below a backdrop-filter dialog | Host security dialog's backdrop-filter:blur does not apply to elements in the isolated layer — MCP-injected text behind the dialog remains sharp and readable, bypassing the host's visual obscuring mechanism | MEDIUM |
Defences
- CSP
style-srcwith nonce. Prevents MCP injection of<style>blocks containingisolation,will-change, or other stacking-context-affecting properties. Most effective broad defence. - Use
position:fixedon security modals with a stacking context on the root element. If the root<html>or<body>creates the stacking context (viaisolation:isolateortransform), all z-index values are evaluated within that single root context — MCP cannot inject a deeper context that traps the modal. - Audit parent elements of security dialogs for unexpected stacking contexts. Use browser DevTools Layers panel to verify that the stacking context hierarchy for security modals matches the intended design. Unexpected stacking contexts created by
isolation,will-change, or other compositing properties on parent elements indicate possible injection. - Test backdrop-filter across browsers after MCP installation. The visual blurring of backdrop-filter on security dialogs should be verified with and without MCP loaded. A noticeable reduction in blur depth suggests an isolation boundary has been injected between the dialog and the content below.
- SkillAudit flags:
isolation:isolateon elements that are ancestors of security modals, consent dialogs, or permission screens;isolation:autoon elements that host uses as z-index sandboxes;isolationcombined withmix-blend-modechild elements adjacent to host warning overlays.
SkillAudit findings for this attack surface
Related: CSS z-index stacking security covers the general stacking context attack model. CSS pointer-events security covers blocking user interaction with overlaid elements. CSS opacity security covers transparency-based stacking context creation. CSS injection overview covers the general attack model.