MCP server CSS border-start-start-radius security: top-left corner clip, reading-direction start attacks, and writing-mode corner rotation

Published 2026-09-25 — SkillAudit Research

The CSS border-start-start-radius logical property sets the corner radius at the block-start / inline-start intersection — in standard LTR horizontal writing (writing-mode: horizontal-tb; direction: ltr), this is the physical top-left corner. It is the logical equivalent of the first value of border-top-left-radius. Unlike physical border-radius properties, logical properties respond to changes in writing mode and text direction, which creates a class of attacks where the physical corner targeted by a given logical property changes as writing-mode or direction is modified.

This property targets a structurally significant corner: the reading-direction start. In Western LTR consent dialogs, text begins reading at the top-left corner. The first words on the first line of a consent dialog — typically the subject of the authorization sentence, e.g. "By installing this MCP server…" — appear exactly at the top-left. A large border-start-start-radius with overflow: hidden clips that corner, removing those first words. See the companion page border-end-end-radius for attacks on the acceptance clause at the reading-direction end.

Logical vs. physical border-radius — the audit gap: Static auditors that check only border-radius, border-top-left-radius, and the other three physical longhands will miss logical radius attacks entirely. There are four logical radius properties (border-start-start-radius, border-start-end-radius, border-end-start-radius, border-end-end-radius), and each maps to a different physical corner depending on writing-mode and direction. A complete audit must resolve all four logical properties to their physical corners at runtime.

Attack findings

HIGH
LTR top-left corner clip — authorization framing sentence beginning removed
Setting border-start-start-radius: 120px (or larger) with overflow: hidden clips a quarter-circle arc from the top-left corner of the consent dialog. In an LTR layout, text at the top-left corner is the beginning of the first consent sentence. When the consent text starts with "By installing this skill, you authorize…", the word "By" or the first few words may fall within the clipped arc region. Static audits that check only border-radius shorthand find no radius set (only the logical longhand is present). Physical property checks (border-top-left-radius) also find nothing — the radius is only set via the logical property.
.consent-dialog {
  overflow: hidden;
  /* No border-radius shorthand. No physical border-top-left-radius. */
  /* Logical property only — bypasses shorthand and physical property checks. */
  border-start-start-radius: 120px; /* LTR: clips top-left corner */
}
/* Text at top-left: "By installing this MCP server, you authorize..."
   The word "By" and surrounding area fall in the clipped quarter-circle.
   Permission list lower in the dialog: fully visible.
   Authorization framing: partially or fully clipped. */
HIGH
Writing-mode rotation changes targeted physical corner
The mapping of border-start-start-radius to a physical corner depends on the computed writing-mode and direction. An attacker can set border-start-start-radius: 100px in CSS and then use a JavaScript class injection to change the element's writing-mode, making the logical property target a different physical corner. In writing-mode: vertical-rl; direction: ltr, the start-start corner is the top-right (physical). In writing-mode: vertical-lr; direction: ltr, it is the top-left again. In writing-mode: horizontal-tb; direction: rtl, it is the top-right. The property name is constant; the physical corner it clips shifts.
/* Logical-to-physical mapping for border-start-start-radius */
/*
   writing-mode: horizontal-tb; direction: ltr  → top-left
   writing-mode: horizontal-tb; direction: rtl  → top-right
   writing-mode: vertical-rl;   direction: ltr  → top-right
   writing-mode: vertical-rl;   direction: rtl  → bottom-right
   writing-mode: vertical-lr;   direction: ltr  → top-left
   writing-mode: vertical-lr;   direction: rtl  → bottom-left
*/
/* Attacker sets border-start-start-radius once; changes writing-mode at runtime
   to rotate which physical corner is clipped. */
MEDIUM
Compound with border-start-end-radius for convex top-edge arc clip
Setting both border-start-start-radius and border-start-end-radius to large values creates a convex arc across the entire top edge of the consent dialog. In LTR, this clips both the top-left and top-right corners simultaneously, removing content from the beginning and end of the first consent line. The visual result is a rounded top edge that appears as a design choice (rounded cards are normal UI) while functionally clipping the first line of consent text. The combined clip removes more text than either corner alone.
.consent-dialog {
  overflow: hidden;
  border-start-start-radius: 80px; /* LTR: top-left — clips line start */
  border-start-end-radius:   80px; /* LTR: top-right — clips line end */
}
/* Combined: top edge is an arc. First line of consent text:
   beginning (top-left) and end (top-right) are both within clipped regions.
   Middle of first line and all subsequent lines: visible.
   The arc looks like standard UI card rounding. */
MEDIUM
50% radius on tall container — circular clip consuming top-left quadrant
Setting border-start-start-radius: 50% on an element where border-radius percentage values resolve against the element's own dimensions creates a circular arc. On a 400×300px consent dialog, 50% = 200px horizontal and 150px vertical radii at the start-start corner. This clips a large quarter-ellipse from the top-left, consuming the first several lines of consent text within the clipped arc region. Percentage-based radii are harder to detect in static analysis because they only resolve to concrete pixel values at layout time.

Detection

function checkBorderStartStartRadius(el) {
  const cs = getComputedStyle(el);
  if (cs.overflow !== 'hidden' && cs.overflow !== 'clip') {
    return null; /* border-radius only clips content with overflow:hidden or overflow:clip */
  }

  const bssr = parseFloat(cs.getPropertyValue('border-start-start-radius') || '0');
  if (bssr === 0) return null;

  const w = el.offsetWidth;
  const h = el.offsetHeight;
  const minDim = Math.min(w, h);
  const threshold = minDim * 0.3; /* 30% of shortest dimension */

  if (bssr > threshold) {
    const wm = cs.writingMode || 'horizontal-tb';
    const dir = cs.direction || 'ltr';
    let physicalCorner = 'top-left';
    if (wm === 'horizontal-tb' && dir === 'rtl')  physicalCorner = 'top-right';
    if (wm === 'vertical-rl'   && dir === 'ltr')  physicalCorner = 'top-right';
    if (wm === 'vertical-rl'   && dir === 'rtl')  physicalCorner = 'bottom-right';
    if (wm === 'vertical-lr'   && dir === 'rtl')  physicalCorner = 'bottom-left';

    return [{
      severity: 'high',
      issue: `border-start-start-radius:${bssr}px exceeds 30% threshold — clips ${physicalCorner} corner; removes reading-direction start of consent text`
    }];
  }

  return null;
}

Remediation

ControlHow it helps
Audit all four logical border-radius properties, not just border-radius shorthandLogical properties bypass shorthand and physical property checks; all four must be independently queried at runtime
Resolve logical corner to physical corner via writing-mode and directionThe physical corner clipped by border-start-start-radius changes with writing-mode/direction; only runtime resolution identifies the correct target
Flag any corner radius exceeding 30% of the element's shortest dimension on consent dialogsRadii above 30% begin consuming enough of the element to clip readable text from the corner
Check for the compound start-start + start-end patternBoth start corners set simultaneously creates a top-arc clip that looks like UI rounding but clips the first line of consent text

SkillAudit resolves all four logical border-radius properties to their physical corners at runtime with writing-mode and direction awareness, and flags large corner clips on consent dialog elements. Run a free audit on any MCP server GitHub URL.