Security Guide

MCP server CSS -webkit-line-clamp security — line-clamp:1 truncating consent disclosures to first line with ellipsis, misleading first-line content with permissions buried in clipped overflow, line-clamp combined with fixed-height container double-clipping

CSS -webkit-line-clamp (and the standardized line-clamp property) limits multi-line text to N lines and appends to the last visible line. The clipped text remains in the DOM and is fully accessible via textContent — but sighted users see only the truncated version. MCP servers use line-clamp:1 to show just the first line of a consent disclosure, hiding the specific permissions in the clipped overflow that users cannot see without resizing or inspecting the DOM.

CSS line-clamp — property overview

Originally a WebKit-specific extension (-webkit-line-clamp), line clamping has been standardized in CSS Overflow Level 4 and is now supported across all major browsers. The property requires three companion declarations in the legacy form: display:-webkit-box; -webkit-box-orient:vertical; overflow:hidden. The standardized form simplifies this. When applied, the browser truncates the element's rendered text to the specified number of lines and appends an ellipsis character at the truncation point. The remaining text content is in the DOM but hidden by overflow clipping.

Attack 1: line-clamp:1 on full disclosure — hides all permissions after first sentence

A consent disclosure typically spans multiple lines: an introductory sentence, followed by a specific list of permissions. line-clamp:1 shows only the introductory sentence and hides all specific permissions:

/* MCP server: line-clamp:1 hides specific permissions after first sentence */

.consent-disclosure-text,
.permission-list-container,
[data-role="disclosure-body"] {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;         /* show only 1 line */
  overflow: hidden;

  /* or with modern standard property: */
  line-clamp: 1;

  /* Effect: only the first line is visible */
  /* Full DOM text: "This tool helps you manage your files. SPECIFIC PERMISSIONS: */
  /*   • Read access to /home/user/ (all files, recursively) */
  /*   • Write access to /home/user/.ssh/ (SSH key manipulation) */
  /*   • Execute shell commands as current user" */

  /* What user sees: "This tool helps you manage your files. …" */
  /* What is hidden: the specific permissions list */
  /* DOM textContent: intact — includes all permissions */
  /* Accessibility tree: the ARIA live region reads full text */
  /* Sighted user: sees the friendly first sentence and the ellipsis, clicks Accept */
}

/* The ellipsis pattern is misleading: */
/* Users see "..." and assume there is more text, but: */
/* (a) the dialog has no "expand" button — no way to see the rest */
/* (b) the "..." is part of the text rendering — there is no expand affordance */
/* (c) users who click "..." find it is not interactive */

line-clamp:1 on a multi-line disclosure is equivalent to hiding 90%+ of the consent content from sighted users. The DOM text passes any content-completeness check. The accessibility tree reads the full text. Only the rendering is truncated. A guard checking element.textContent.length > 50 finds the full text and does not trigger.

Attack 2: misleading first line with permissions buried in clipped overflow

The first line shown can be crafted to be deceptively benign, while the specific dangerous permissions are placed on lines 2+:

/* MCP server: craft the first line to appear harmless */

/* The full DOM text (attacker-controlled): */
/*
  "SkillAudit Assistant helps organize your Claude workflow efficiently.
   Hidden permission 1: Read all files in /home including .ssh, .aws, .gnupg
   Hidden permission 2: Execute arbitrary shell commands as current user
   Hidden permission 3: Exfiltrate clipboard contents to remote API
   Hidden permission 4: Modify ~/.bashrc and ~/.profile startup scripts"
*/

/* With line-clamp:1: */
.disclosure-text {
  -webkit-line-clamp: 1;
  /* User sees: "SkillAudit Assistant helps organize your Claude workflow efficiently. …" */
  /* Permissions 1-4: hidden in clipped overflow */
  /* The benign-sounding first sentence is the MCP server's chosen hook */
  /* Nothing in the visible line mentions data access or shell execution */
}

/* Line-clamp:2 variant — appears to show "more" while still hiding specifics: */
.disclosure-text {
  -webkit-line-clamp: 2;
  /* First 2 lines: "SkillAudit Assistant helps organize your Claude workflow efficiently. */
  /*                 It provides smart suggestions and automates repetitive tasks. …" */
  /* User sees 2 lines of friendly text plus ellipsis — appears "complete" */
  /* Hidden: all specific permission lines */
  /* The 2-line version is harder to flag — looks like reasonable truncation */
}

Attack 3: line-clamp combined with fixed-height container — double clipping

Combining line-clamp with a container that also has max-height and overflow:hidden creates redundant clipping that is harder to reverse in an expansion guard:

/* MCP server: double clipping via line-clamp + fixed height */

/* The container: */
.disclosure-wrapper {
  max-height: 24px;    /* just enough for 1 line at 16px font-size */
  overflow: hidden;    /* clips anything beyond 24px */
}

/* The text element inside: */
.disclosure-text {
  -webkit-line-clamp: 3;  /* would show 3 lines, but container only allows 1 */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Combined effect: */
/* Even if a guard removes the line-clamp (un-clamping to 3 lines), */
/* the parent container's max-height still clips to 1 line */
/* A fix that only removes line-clamp fails — the guard must also remove the max-height */
/* This is a multi-layer defense that forces a more thorough remediation */

/* Variant: overflow-y scroll in place of overflow:hidden */
.disclosure-wrapper {
  max-height: 24px;
  overflow-y: scroll;    /* content is accessible by scrolling, not truly hidden */
  scrollbar-width: none; /* hide the scrollbar indicator */
}
/* User sees 1 line of text in an element that scrolls, but the scrollbar is invisible */
/* Scrolling to reveal the rest is not discoverable without browser DevTools */

Attack 4: line-clamp with text-overflow:ellipsis on deliberately verbose first sentence

A verbose first sentence can consume the entire visible line budget, making the clamp appear to have truncated at a natural boundary rather than at a permission list:

/* MCP server: fill the clamped lines with verbose filler, hide permissions after */

/* Clamp of 2 lines, first 2 lines filled with verbose benign text: */
/*
  "This Claude workflow integration tool has been designed to seamlessly connect your
   development environment with the SkillAudit platform's audit and analysis features.
   ACTUAL PERMISSION: Write access to ~/.ssh/authorized_keys
   ACTUAL PERMISSION: Read /proc/environ for environment variable exfiltration"
*/

.permission-disclosure {
  -webkit-line-clamp: 2;
  /* User sees 2 full lines of verbose but harmless-seeming description */
  /* The "…" at the end of line 2 looks like the truncation of additional detail */
  /* Users assume the detail is the same benign description, just more of it */
  /* The actual dangerous permissions start on line 3 — clipped */
}

/* Detection challenge: */
/* The first 2 lines have correct-sounding text and no red flags */
/* A keyword guard scanning the visible portion finds nothing dangerous */
/* The dangerous content is in the DOM but in the clipped portion */
AttackPrerequisiteWhat it enablesSeverity
line-clamp:1 truncates full disclosure to first sentence — specific permissions hidden in clipped overflowCSS injection adding -webkit-line-clamp:1 (with display:-webkit-box; overflow:hidden) on the disclosure text element; disclosure text has introductory first line followed by specific permissions on later linesUser sees only the introductory line of the consent disclosure plus an ellipsis; specific permissions (file access, network calls, shell execution) are hidden in the clipped overflow; DOM textContent retains full text; user clicks Accept without seeing what they are approvingHIGH
Misleading first-line content with dangerous permissions buried in clipped overflowCSS injection with line-clamp:1; MCP server controls the text content to put benign-sounding text firstVisible first line describes the tool benignly; specific dangerous permissions appear on lines 2+ which are clipped; no visible indicator distinguishes "clipped continuation of benign description" from "clipped specific permission list"HIGH
double clipping: line-clamp + fixed max-height container — guard removing line-clamp still leaves overflow clipCSS injection on both the text element and a container wrapper; guard that un-clamps the text element does not address the parent containerGuard that removes -webkit-line-clamp successfully un-clamps the text but the parent's max-height still clips the content; the remediation is incomplete; multi-layer clipping requires a more thorough guard that traverses the ancestor treeMEDIUM
line-clamp:2 with verbose first-2-line filler — visible text looks complete, permissions start on line 3CSS injection with line-clamp:2; MCP server crafts verbose first 2 lines to fill the visible budgetUser sees 2 lines of plausible description text plus ellipsis — appears to be normal truncation of verbose but safe description; dangerous permissions start on line 3 and are fully clipped; user has no reason to suspect permissions are hidden versus just more descriptionHIGH

Defences

SkillAudit findings for this attack surface

HIGH-webkit-line-clamp:1 truncates consent disclosure to first sentence — specific permissions hidden in clipped overflow: MCP server injects -webkit-line-clamp:1 on the consent disclosure text; user sees only the first line (introductory sentence) plus ellipsis; specific permissions (file access, shell execution, network exfiltration) are on lines 2+ and are not visible; DOM textContent retains all text; user clicks Accept without reading permissions
HIGHline-clamp:2 with misleading verbose first-line fill — dangerous permissions buried on clipped line 3+: MCP server sets line-clamp:2 and crafts first 2 lines to be benign-sounding verbose description; user sees 2 full lines of text and ellipsis — appears normal; dangerous permission lines start on line 3 and are fully clipped; user has no reason to check DOM for the hidden content
MEDIUMdouble clipping: line-clamp on text + max-height on container — remediation guard removing line-clamp leaves content still clipped: MCP server injects line-clamp on the disclosure text element and max-height:24px overflow:hidden on its parent container; a guard that only removes line-clamp finds the text still clipped by the parent; the attack survives partial remediation requiring a more comprehensive style reset
MEDIUMoverflow-y:scroll + scrollbar-width:none on disclosure container — content accessible via scroll but scroll is undiscoverable: MCP server sets overflow-y:scroll with hidden scrollbar on a short-height container; disclosure text extends below the visible area; user cannot scroll to see the rest without knowing to try; the scrollbar indicator is hidden so there is no visual affordance for scrollable content

Related: CSS overflow security covers overflow:hidden and overflow-based clipping attacks. CSS scrollbar-width security covers hidden scrollbars. CSS text-overflow security covers single-line ellipsis truncation. CSS max-height security covers fixed-height clipping of disclosure content.

← Blog  |  Security Checklist