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.

AttackPrerequisiteWhat it enablesSeverity
isolation:isolate creates silent stacking context — host security modal z-index trapped inside new contextCSS injection on an ancestor element of the host security modal + a new MCP overlay with higher z-index inside the same contextHost 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 possibleHIGH
isolation:auto removing intentional host stacking context — MCP elements escape z-index sandboxCSS injection removing will-change/transform/opacity/filter from host sandbox containerMCP 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-indexHIGH
isolation:isolate changing mix-blend-mode compositing scope — warning overlay effect reducedCSS injection setting isolation:isolate on a container ancestor of a blend-mode security overlayHost 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 prominentMEDIUM
isolation:isolate blocking backdrop-filter from blurring MCP content behind security dialogsCSS injection setting isolation:isolate on a layer containing MCP content below a backdrop-filter dialogHost 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 mechanismMEDIUM

Defences

SkillAudit findings for this attack surface

HIGHisolation:isolate silently creates stacking context — host security modal z-index trapped: MCP server injects isolation:isolate on an ancestor of the host security modal — the modal's z-index is now evaluated within the new context rather than the root context; a higher MCP z-index within the same context renders above the modal, replacing the consent dialog, permission prompt, or 2FA screen
HIGHisolation:auto collapses host z-index sandbox — MCP elements escape to root stacking context: MCP server removes stacking-context-forming properties (will-change, transform, opacity) from a host sandbox container via isolation:auto and property resets — MCP overlay elements now participate in the root stacking context and can render above any host element
MEDIUMisolation:isolate changes mix-blend-mode compositing scope — warning overlay reduced: MCP server injects isolation:isolate on a container ancestor of a blend-mode security warning — the overlay composites against the isolated container background instead of actual page content, reducing the warning's visual contrast and prominence
MEDIUMisolation:isolate blocks backdrop-filter from blurring MCP content behind security dialogs: MCP server creates an isolated compositing layer below a host backdrop-filter:blur dialog — MCP-injected content in the isolated layer remains sharp, bypassing the host's visual obscuring mechanism and allowing readable deceptive content behind the dialog

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.

← Blog  |  Security Checklist