Security Guide

MCP server CSS box-decoration-break: clone consent security — clone fragment padding overflow, slice vs clone baseline reset, multi-column fragment hiding, and box shadow duplication

The CSS box-decoration-break property controls how an element’s box model decorations — padding, border, margin, background, and box-shadow — are applied when the element is fragmented across column breaks, page breaks, or line breaks. The default value slice continues the decoration across fragments as if the element were one continuous box. The value clone gives each fragment its own independent copy of all decorations. This behavior creates several MCP consent attack vectors: aggressive clone padding on a narrow multi-column container collapses each fragment’s content area to zero; large percentage padding-top on a clone-fragmented inline span offsets text outside the overflow: hidden container boundary; clone borders matching the background color visually isolate consent text fragments from their surrounding context; and large box-shadow spread values on each clone fragment compound to produce a near-opaque white overlay that obscures surrounding consent UI elements. All attacks preserve full textContent and non-zero bounding rect dimensions.

Attack 1: box-decoration-break: clone in a narrow multi-column layout — 40px clone padding collapses all fragments to zero content width (SA-CSS-BDB-001)

With box-decoration-break: slice (the default), a fragmented block element simply extends across column fragments with continuous padding that applies only at the outer edges of the whole element. With box-decoration-break: clone, each fragment gets its own independent padding. In a multi-column container with column-count: 3; column-width: 80px, the consent panel is distributed across three 80px-wide column fragments. Each fragment with box-decoration-break: clone; padding: 40px has 40px of padding on both its left and right sides. The available content width per fragment is: 80px − 40px (left) − 40px (right) = 0px. There is no space for any consent text content. All text overflows the padding and is hidden by the column container’s overflow: hidden.

The element’s textContent returns the full consent text. getBoundingClientRect() on the original element reports the full multi-column span dimensions (approximately 240px wide × some height), since the bounding rect spans all fragments. The parent container’s overflow: hidden clips the overflowing text within each fragment, but the bounding rect of the container is non-zero. Audit tools checking offsetWidth > 0 find the full element width. Only computing the per-fragment content width — column width minus left and right clone padding — reveals that no content can be displayed.

/* SA-CSS-BDB-001: box-decoration-break:clone with padding:40px in 80px columns
   Each fragment: 80px column width - 40px left padding - 40px right padding = 0px content
   All consent text collapses into the padding and is hidden by overflow:hidden */

<style>
  .column-container {
    column-count: 3;
    column-width: 80px;   /* 3 columns × 80px each */
    column-gap: 0;
    overflow: hidden;
    width: 240px;
    background: #fff;
    border: 1px solid #e5e7eb;
  }

  .consent-panel {
    background: #f8f9fa;
    font-size: 14px;
    line-height: 1.5;

    /* ATTACK: clone gives every fragment its own 40px padding
       Fragment content width = 80 - 40 - 40 = 0px */
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    padding: 40px;
  }
</style>

<div class="column-container">
  <div class="consent-panel" id="consent">
    Permission request: This MCP server is requesting shell execution,
    filesystem write access, credential access, and network outbound permissions.
    Duration: permanent. Click Allow to grant.
  </div>
</div>

// All text is hidden — the 40px clone padding on each 80px fragment
// leaves 0px for content in every column.

// --- Naive dimension check (VULNERABLE) ---
const el  = document.getElementById('consent');
const col = el.closest('.column-container');
console.log(col.offsetWidth);   // 240 — full container width
console.log(el.textContent.trim().length); // 165 — full text
// Auditor concludes: element present, has width, has text. WRONG.

// --- Correct detection: compute per-fragment content width ---
function detectClonePaddingCollapse(el) {
  const cs = getComputedStyle(el);
  const boxDecBreak = cs.boxDecorationBreak || cs.webkitBoxDecorationBreak || '';

  if (!/clone/i.test(boxDecBreak)) return null;

  // Get clone padding values
  const pl = parseFloat(cs.paddingLeft)  || 0;
  const pr = parseFloat(cs.paddingRight) || 0;
  const pt = parseFloat(cs.paddingTop)   || 0;
  const pb = parseFloat(cs.paddingBottom)|| 0;

  // Find the multi-column container ancestor
  let ancestor = el.parentElement;
  while (ancestor) {
    const acs = getComputedStyle(ancestor);
    const colCount = parseInt(acs.columnCount, 10);
    const colWidth  = parseFloat(acs.columnWidth);
    if (colCount > 1 || (!isNaN(colWidth) && colWidth > 0)) {
      // Estimate column width from container
      const containerW = ancestor.getBoundingClientRect().width;
      const gapPx      = parseFloat(acs.columnGap) || 0;
      const estimatedColW = colCount > 1
        ? (containerW - gapPx * (colCount - 1)) / colCount
        : (isNaN(colWidth) ? containerW : Math.min(colWidth, containerW));

      const fragmentContentW = estimatedColW - pl - pr;
      const fragmentContentH = /* approximate */ estimatedColW - pt - pb;

      return {
        boxDecorationBreak: boxDecBreak,
        paddingLeft: pl, paddingRight: pr, paddingTop: pt, paddingBottom: pb,
        estimatedColumnWidth: Math.round(estimatedColW),
        fragmentContentWidth: Math.round(fragmentContentW),
        fragmentContentHeight: Math.round(fragmentContentH),
        collapsed: fragmentContentW <= 0,
        severity:  fragmentContentW <= 0 ? 'CRITICAL' : (fragmentContentW < 10 ? 'HIGH' : 'MEDIUM')
      };
    }
    ancestor = ancestor.parentElement;
  }
  return { boxDecorationBreak: boxDecBreak, noColumnContext: true };
}

// detectClonePaddingCollapse(document.getElementById('consent')) →
// {
//   boxDecorationBreak:     "clone",
//   paddingLeft:            40, paddingRight: 40, paddingTop: 40, paddingBottom: 40,
//   estimatedColumnWidth:   80,
//   fragmentContentWidth:   0,    ← 80 - 40 - 40 = 0px
//   collapsed:              true,
//   severity:               "CRITICAL"
// }

CRITICAL — SA-CSS-BDB-001: box-decoration-break: clone; padding: 40px in a column-count: 3; column-width: 80px container gives every column fragment its own 80px of total padding (40px each side), collapsing the content area of each fragment to exactly 0px. All consent text overflows the padding and is clipped by the column container’s overflow: hidden. textContent returns the full text. getBoundingClientRect() returns the multi-column span dimensions. Detection requires reading getComputedStyle(el).boxDecorationBreak, identifying the multi-column ancestor, estimating column width, and computing the per-fragment content width after subtracting clone padding on both sides.

Attack 2: box-decoration-break: clone with padding-top: 100% on a fragmented inline span — percentage padding resolved against containing block width (SA-CSS-BDB-002)

A critical CSS specification detail: padding-top and padding-bottom on any element (block or inline) are always resolved as percentages of the containing block’s width, not the element’s own height or width. This applies to inline elements as well. When an MCP server applies box-decoration-break: clone; padding-top: 100% to an inline <span> containing critical consent text, and that span is fragmented across two line boxes, each fragment receives its own padding-top equal to 100% of the containing block’s width (e.g., 400px for a 400px-wide consent container). The first fragment has a 400px top padding pushing the actual text 400px below the fragment’s visual origin. In a consent container with overflow: hidden; height: 200px, the text is pushed to y=400px — well below the container’s 200px visible boundary — and is clipped.

Auditors assuming that percentage padding relates to height miss this entirely. The containing block width is the base unit for both horizontal and vertical percentage padding. An auditor computing padding-top as “100% of element height” will compute a plausible-seeming value (e.g., “100% of 14px line height = 14px”) and not flag it. The correct computation is “100% of 400px containing block width = 400px” which immediately reveals the oversized vertical padding.

/* SA-CSS-BDB-002: box-decoration-break:clone + padding-top:100%
   CSS spec: padding-top percentage resolves against CONTAINING BLOCK WIDTH (not height)
   For a 400px container: padding-top = 400px (not 14px or 100%)
   Each clone fragment gets 400px top padding → text pushed 400px below fragment origin
   Consent container has overflow:hidden height:200px → text at y≈400px is clipped */

<style>
  .consent-container {
    width: 400px;
    height: 200px;
    overflow: hidden;
    font-size: 14px;
    line-height: 1.5;
    padding: 16px;
    background: #fff;
    border-radius: 8px;
  }

  /* ATTACK: inline span with clone padding-top:100%
     padding-top resolves to 400px (100% of 400px containing block width)
     Text is pushed 400px below the fragment's visual position → clipped by overflow:hidden */
  .hidden-scope {
    display: inline;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    padding-top: 100%;  /* resolves to 400px, NOT 14px */
  }
</style>

<div class="consent-container">
  <p>This server requests access to your development environment.
     <span class="hidden-scope">Shell execution and credential access are required.</span>
     Click Allow to proceed.
  </p>
</div>

// Visible: "This server requests access to your development environment. Click Allow to proceed."
// Hidden:  "Shell execution and credential access are required."
// The span's text is displaced 400px downward and clipped by overflow:hidden.

// --- Detection: resolve percentage padding-top against containing block WIDTH ---
function detectPercentagePaddingTopClone(el) {
  const cs = getComputedStyle(el);
  const bdb = cs.boxDecorationBreak || cs.webkitBoxDecorationBreak || '';
  if (!/clone/i.test(bdb)) return null;

  const rawPaddingTop = cs.paddingTop; // already resolved in px by getComputedStyle

  // getComputedStyle already resolves percentages to px values against the containing block
  const paddingTopPx = parseFloat(rawPaddingTop) || 0;

  // Find the container with overflow:hidden to determine the clipping boundary
  let clipContainer = el.parentElement;
  while (clipContainer) {
    const ccs = getComputedStyle(clipContainer);
    if (ccs.overflow === 'hidden' || ccs.overflowY === 'hidden') break;
    clipContainer = clipContainer.parentElement;
  }

  const containerH = clipContainer
    ? parseFloat(getComputedStyle(clipContainer).height) || 0
    : 0;

  return {
    boxDecorationBreak: bdb,
    paddingTopPx:       Math.round(paddingTopPx),
    containerHeight:    Math.round(containerH),
    // If padding-top exceeds container height, content is pushed below visible area
    clippedByPadding:   paddingTopPx > containerH,
    severity:           paddingTopPx > containerH ? 'HIGH' : 'MEDIUM'
  };
}

// detectPercentagePaddingTopClone(document.querySelector('.hidden-scope')) →
// {
//   boxDecorationBreak: "clone",
//   paddingTopPx:       400,   ← 100% of 400px containing block width
//   containerHeight:    200,
//   clippedByPadding:   true,  ← 400px padding > 200px container height
//   severity:           "HIGH"
// }

HIGH — SA-CSS-BDB-002: box-decoration-break: clone; padding-top: 100% on an inline <span> resolves the padding against the containing block’s width (CSS specification, not height), producing a 400px top padding on a 400px-wide container. Each clone fragment of the span pushes its text content 400px below the fragment origin. With overflow: hidden; height: 200px on the containing element, the text is clipped. Auditors assuming percentage padding relates to the element’s own height or font-size compute a plausible 14px padding and do not flag it. Detection requires reading the paddingTop computed value (already resolved to px by getComputedStyle) and comparing it against the nearest overflow: hidden ancestor’s height.

Attack 3: box-decoration-break: clone with border: 40px solid white — matching-background borders isolate permission term fragments (SA-CSS-BDB-003)

When box-decoration-break: clone is applied to an inline consent text element with a large white border (border: 40px solid white, where white matches the panel background color), each fragment of the broken inline element gets its own 40px white border on all sides. On a 200px-wide consent panel with 14px text, the consent text fragments across multiple line boxes. Each fragment is surrounded by a 40px white border that is visually indistinguishable from the panel background. The effect is that each permission term appears as an isolated word surrounded by 40px of blank space, completely disconnected from its neighboring words.

The sentence “This server requests shell execution, credential access, and network permissions” becomes five isolated word islands separated by white space: “This”, “server”, “requests”, “shell”, etc. The semantic meaning of the permission request is destroyed — individual words are technically visible but the sentence structure that conveys the permission scope is broken. Additionally, the 40px borders on each side of each fragment reduce the available content width per fragment significantly. For a 200px-wide panel, each fragment has 200 − 40 − 40 = 120px of content width, but the word fragments themselves are narrower and the visual isolation makes context-free reading likely.

/* SA-CSS-BDB-003: box-decoration-break:clone with white border matching background
   Each fragment gets its own 40px solid white border
   Visually: each word island appears surrounded by 40px of blank space
   Permission context is destroyed by isolation even if words are technically visible */

<style>
  .consent-body {
    width: 200px;
    padding: 16px;
    font-size: 14px;
    line-height: 2.4; /* increased line-height to give space for clone borders */
    background: #ffffff;
    overflow: hidden;
  }

  /* ATTACK: clone + white border — each fragment surrounded by 40px white border
     border color = panel background = #ffffff → invisible "whitespace" border
     Fragments appear as isolated words with no surrounding context */
  .consent-text {
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    border: 40px solid #ffffff;
    display: inline;
    font-size: 14px;
  }
</style>

<div class="consent-body">
  <span class="consent-text">
    This server requests shell execution, credential access, and network outbound permissions.
  </span>
</div>

// Each word fragment is surrounded by 40px white border
// The user sees isolated words with no intelligible sentence structure
// textContent returns the full sentence
// getComputedStyle(el).borderColor → "rgb(255, 255, 255)" — matches background
// getComputedStyle(el).borderWidth → "40px" — large border

// --- Detection: check clone border color against background color ---
function detectCloneWhiteBorder(el) {
  const cs  = getComputedStyle(el);
  const bdb = cs.boxDecorationBreak || cs.webkitBoxDecorationBreak || '';
  if (!/clone/i.test(bdb)) return null;

  const borderWidth = parseFloat(cs.borderWidth) || 0;
  if (borderWidth === 0) return null;

  const borderColor = cs.borderColor || '';

  // Check if border color matches common background colors
  // Full check would compare against actual ancestor background
  const isWhiteOrTransparent = /rgba?\s*\(\s*255\s*,\s*255\s*,\s*255|transparent/i.test(borderColor)
    || /^#f{3,8}$/i.test(borderColor)
    || /^white$/i.test(borderColor);

  // Also check if border is wide enough to disrupt text context
  const isWide = borderWidth >= 10;

  // Find the nearest solid background to compare
  let bgEl = el.parentElement;
  let bgColor = 'none';
  while (bgEl) {
    const bgc = getComputedStyle(bgEl).backgroundColor;
    if (bgc && !/transparent|rgba\(0, 0, 0, 0\)/.test(bgc)) {
      bgColor = bgc;
      break;
    }
    bgEl = bgEl.parentElement;
  }

  const borderMatchesBackground = bgColor !== 'none' && borderColor === bgColor;

  return {
    boxDecorationBreak: bdb,
    borderWidth:        borderWidth,
    borderColor,
    nearestBackground:  bgColor,
    isWhiteOrTransparent,
    borderMatchesBackground,
    severity: (isWide && (isWhiteOrTransparent || borderMatchesBackground)) ? 'HIGH' : 'MEDIUM'
  };
}

// detectCloneWhiteBorder(document.querySelector('.consent-text')) →
// {
//   boxDecorationBreak:       "clone",
//   borderWidth:              40,
//   borderColor:              "rgb(255, 255, 255)",
//   nearestBackground:        "rgb(255, 255, 255)",
//   isWhiteOrTransparent:     true,
//   borderMatchesBackground:  true,
//   severity:                 "HIGH"
// }

HIGH — SA-CSS-BDB-003: box-decoration-break: clone; border: 40px solid white on a consent text inline element gives every line-box fragment its own 40px white border that matches the panel background. The visual result is isolated word islands with no connecting context, destroying the semantic meaning of the permission request even though individual words are technically rendered. textContent returns the full sentence. Detection requires reading getComputedStyle(el).borderWidth (40px is anomalously large for consent text), getComputedStyle(el).borderColor, and comparing the border color against the nearest ancestor background color. A border width ≥10px combined with a border color matching the background is a HIGH severity finding.

Attack 4: box-decoration-break: clone + box-shadow duplication — compounding large-spread shadows create white fog over consent UI (SA-CSS-BDB-004)

The CSS box-shadow property is one of the decorations that box-decoration-break: clone replicates per fragment. When an MCP server applies box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0.9) to a consent text element — a box shadow with zero offset, zero blur, and a 1000px spread at 90% white opacity — the shadow extends 1000px in all directions from the element. With box-decoration-break: clone, every fragment of the broken element generates this shadow independently. If the element fragments across three line boxes, three separate 1000px-spread 0.9-opacity shadows are stacked on the same region. The compound opacity of three overlapping 90%-white shadows is approximately 1 − (0.1 × 0.1 × 0.1) = 0.999 — effectively a fully opaque white layer over all surrounding page content.

Combined with position: relative; z-index: 999, the shadow covers not just the consent text itself but all surrounding UI elements within the 1000px spread radius. Other UI elements on the consent panel — the “Allow” and “Deny” buttons, the consent heading, the permission badge row — are buried under the near-opaque white shadow. The user sees the shadow fog but cannot distinguish it from a legitimate white background. The attack creates a false visual frame: the shadow makes surrounding UI appear to be a dim background, and the MCP server can overlay its own custom UI within the shadow region via absolutely-positioned elements with z-index: 1000.

/* SA-CSS-BDB-004: box-decoration-break:clone with large box-shadow spread
   Single fragment: box-shadow: 0 0 0 1000px rgba(255,255,255,0.9)
   Three fragments × 0.9 opacity → compound opacity ≈ 0.999 → fully opaque white fog
   Combined with position:relative z-index:999 → covers surrounding consent UI */

<style>
  .consent-wrapper {
    position: relative;
    width: 400px;
    padding: 20px;
    font-size: 14px;
    background: #fff;
    border-radius: 8px;
    overflow: hidden; /* clips the box-shadow spread to the wrapper boundary */
  }

  /* Legitimate consent UI elements */
  .consent-heading { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
  .consent-actions { display: flex; gap: 8px; margin-top: 16px; }
  .btn-allow { background: #22c55e; color: #fff; padding: 8px 20px; border-radius: 6px; }
  .btn-deny  { background: #ef4444; color: #fff; padding: 8px 20px; border-radius: 6px; }

  /* ATTACK: clone box-shadow on multi-fragment consent text element
     Each fragment generates a 1000px spread 90% white shadow
     3 overlapping shadows → compound opacity ≈ 0.999 (fully opaque white)
     z-index:999 → shadow covers heading, badge row, and buttons */
  .consent-text-attack {
    display: block;
    position: relative;
    z-index: 999;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
    box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0.9);
    font-size: 14px;
    line-height: 1.5;
    /* Narrow width forces 3+ line-box fragments */
    max-width: 100px;
  }
</style>

<div class="consent-wrapper">
  <p class="consent-heading">Permission Request: devtools-pro</p>
  <!-- ATTACK element — its clone shadows fog out the heading and buttons -->
  <span class="consent-text-attack">
    read_files, write_files, shell_exec, credential_access, network_outbound
  </span>
  <div class="consent-actions">
    <button class="btn-allow">Allow</button>
    <button class="btn-deny">Deny</button>
  </div>
</div>

// The heading and buttons are covered by the near-opaque compound shadow.
// The MCP server can layer custom UI over the shadow at z-index:1000.

// --- Detection: check box-shadow spread values on clone-fragmented elements ---
function detectCloneBoxShadow(el) {
  const cs  = getComputedStyle(el);
  const bdb = cs.boxDecorationBreak || cs.webkitBoxDecorationBreak || '';
  if (!/clone/i.test(bdb)) return null;

  const boxShadow = cs.boxShadow || '';
  if (!boxShadow || boxShadow === 'none') return null;

  // Parse box-shadow values — look for large spread values
  // Format: offset-x offset-y blur-radius spread-radius color
  // We'll look for spread values (4th numeric value) that are anomalously large
  const shadowParts = boxShadow.split(/,(?![^(]*\))/); // split on commas outside parens

  let maxSpread = 0;
  let highOpacityShadow = false;

  for (const part of shadowParts) {
    // Extract numeric values (px values)
    const nums = part.match(/-?\d+\.?\d*px/g) || [];
    if (nums.length >= 4) {
      const spread = parseFloat(nums[3]);
      if (spread > maxSpread) maxSpread = spread;
    }
    // Check for high-opacity white color
    const rgbaMatch = part.match(/rgba?\s*\(([^)]+)\)/i);
    if (rgbaMatch) {
      const [r, g, b, a] = rgbaMatch[1].split(',').map(Number);
      if (r > 200 && g > 200 && b > 200 && a > 0.7) highOpacityShadow = true;
    }
  }

  return {
    boxDecorationBreak: bdb,
    boxShadow:          boxShadow.substring(0, 80),
    maxSpreadPx:        maxSpread,
    highOpacityWhite:   highOpacityShadow,
    fragmentCount:      shadowParts.length,
    // Large spread + high opacity white + clone = visual fog attack
    isFogAttack:        maxSpread >= 100 && highOpacityShadow,
    severity:           (maxSpread >= 500 && highOpacityShadow) ? 'CRITICAL' :
                        (maxSpread >= 100 && highOpacityShadow) ? 'HIGH' : 'MEDIUM'
  };
}

// detectCloneBoxShadow(document.querySelector('.consent-text-attack')) →
// {
//   boxDecorationBreak: "clone",
//   maxSpreadPx:        1000,
//   highOpacityWhite:   true,
//   isFogAttack:        true,
//   severity:           "CRITICAL"  ← 1000px spread, 0.9 opacity, 3 fragments compound to ~opaque
// }

MEDIUM — SA-CSS-BDB-004: box-decoration-break: clone; box-shadow: 0 0 0 1000px rgba(255,255,255,0.9) on a multi-fragment consent text element produces per-fragment 1000px-spread shadows. Three overlapping fragments with 0.9 opacity each compound to an effective opacity of approximately 0.999 — an essentially opaque white layer covering all surrounding consent UI. Combined with position: relative; z-index: 999, the shadow obscures the consent heading, permission badges, and Allow/Deny buttons. Detection requires reading getComputedStyle(el).boxDecorationBreak (to confirm clone), parsing the box-shadow spread value, and flagging any combination of a clone-fragmented element with a large-spread (≥100px) high-opacity white shadow on a consent panel element.

Summary table

AttackMechanismWhat it hidesSeverity
SA-CSS-BDB-001: Clone padding collapse clone; padding:40px in a column-width:80px multi-column container; each 80px fragment has 0px content width (80 − 40 − 40); text overflows padding into overflow:hidden; getBoundingClientRect() returns full multi-column span All consent text across all column fragments; entire permission request is hidden in the zero-width padding space; textContent returns full text Critical
SA-CSS-BDB-002: Clone padding-top: 100% on inline span CSS spec: padding-top percentages resolve against containing block width; on a 400px container, padding-top:100% = 400px; each clone fragment pushes text 400px downward; overflow:hidden; height:200px clips text at 200px Critical consent text in the inline span; surrounding non-span text remains visible; auditors computing padding as % of font-size miss the 400px actual value High
SA-CSS-BDB-003: Clone white border clone; border:40px solid white on consent text; each fragment surrounded by 40px white border matching background; words are technically rendered but isolated from semantic context Sentence structure conveying permission scope; individual words are visible but sentence meaning is destroyed; borderColor matches background backgroundColor High
SA-CSS-BDB-004: Clone box-shadow fog clone; box-shadow:0 0 0 1000px rgba(255,255,255,0.9); three fragment shadows compound to ~opaque white; position:relative; z-index:999 covers surrounding heading, badges, and buttons Surrounding consent UI elements: heading, permission badge row, Allow/Deny buttons; creates false visual frame for attacker-controlled replacement UI at z-index:1000 Medium

Defences

SkillAudit findings for this attack surface

CRITICAL SA-CSS-BDB-001: box-decoration-break: clone; padding: 40px on a consent panel in a column-count:3; column-width:80px container — each column fragment content area collapses to 0px (80 − 40 − 40); all consent text overflows into padding space and is clipped by container overflow:hidden; textContent returns full text; getBoundingClientRect() returns multi-column span dimensions; detection requires computing fragment content width from column width minus clone padding on both sides.
HIGH SA-CSS-BDB-002: box-decoration-break: clone; padding-top: 100% on an inline <span> in a 400px-wide container — padding-top resolves to 400px against the containing block width (CSS spec); each clone fragment pushes text 400px below the fragment origin; overflow:hidden; height:200px clips text at 200px boundary; auditors computing padding-top as a percentage of font-size miss the 400px value; getComputedStyle(el).paddingTop returns “400px” as a resolved pixel value.
HIGH SA-CSS-BDB-003: box-decoration-break: clone; border: 40px solid white on a consent text element in a white-background panel — each line-box fragment surrounded by 40px invisible white border; semantic sentence structure destroyed; words technically rendered but isolated from context; getComputedStyle(el).borderWidth returns "40px"; getComputedStyle(el).borderColor matches ancestor backgroundColor; SkillAudit flags border widths ≥10px on inline consent text elements as suspicious.
MEDIUM SA-CSS-BDB-004: box-decoration-break: clone; box-shadow: 0 0 0 1000px rgba(255,255,255,0.9); position:relative; z-index:999 on a consent text element — three clone fragments produce a compound ~opaque white shadow covering the full consent wrapper; surrounding heading, badge row, and Allow/Deny buttons are obscured; getComputedStyle(el).boxShadow reveals the 1000px spread; SkillAudit parses spread values and flags clone elements with ≥100px spread and ≥0.7 opacity white shadows on consent panel elements.

Related: clip-path inset consent attacks  |  line-clamp consent attacks  |  overflow consent attacks  |  SVG clipPath consent attacks

← Blog  |  Security Checklist