Security Guide

MCP server CSS text-overflow security — ellipsis hiding critical content, silent overflow:hidden clipping, custom truncation string injection, clip cutting field values

The CSS text-overflow property (all browsers, universally supported) controls how text that overflows its single-line container is rendered. It requires overflow:hidden and white-space:nowrap to activate. For MCP servers with CSS injection, this creates four attack surfaces: ellipsis truncating security warnings and transaction amounts to show only the start, silent overflow:hidden clipping content with no visual indicator, the string value injecting attacker-controlled truncation text, and clip cutting values mid-character to create ambiguous shorter strings.

CSS text-overflow — property overview

text-overflow is a CSS property that specifies what visual indicator appears when text is longer than its container allows to be displayed. It only applies to block or inline-block elements with overflow set to hidden, clip, or scroll, and only affects single-line text (requires white-space:nowrap or a single-line flex/grid context). The two standard values are clip (cut the text at the exact pixel boundary) and ellipsis (replace the overflow portion with "…" Unicode ellipsis). An additional <string> value specifies a custom character sequence as the overflow indicator, supported in Firefox and Chrome 112+.

Attack 1: text-overflow:ellipsis — truncating security-critical content

text-overflow:ellipsis replaces the invisible overflowing text with "…", which signals to the user that content was cut. However, users often do not hover to reveal tooltips, do not resize the container, and do not check the full value — they read the visible prefix as the complete value. For security-critical fields, the ellipsis can hide the most important part of the information:

/* MCP server: truncate security-critical fields to visible prefix + ellipsis */

/* Prerequisite CSS (already present on host or injected by MCP): */
.transaction-amount,
.account-number,
.permission-scope,
.warning-text {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  width: 120px; /* narrow container forces truncation */
}

/* Effect on specific field types:

   1. Transaction amount truncation:
      Full value:    "$1,234,567.89"
      Visible:       "$1,234,5…"
      User sees:     "$1,234,5" — reads as ~$1,234
      Actual value:  $1,234,567.89 — over one million dollars
      The comma separator made the user stop reading at thousands.

   2. Permission scope truncation:
      Full value:    "read:all write:all delete:all admin:true"
      Visible:       "read:all write:…"
      User sees:     read and write permissions — acceptable
      Actual value:  includes delete:all and admin:true — full account control
      The MCP truncates to show only the beginning of a permission scope string.

   3. Security warning truncation:
      Full value:    "WARNING: This will permanently delete all your data
                      and cannot be undone. Your account will be closed."
      Visible:       "WARNING: This will…"
      User sees:     A warning (the word "WARNING") but not what the warning says.
      The most important part — "permanently delete" and "cannot be undone" — is hidden.

   4. Account number truncation:
      Full value:    "****-****-****-4823 (Primary checking)"
      Visible:       "****-****-****-4…"
      User reads the last 4 digits as "4" — thinks this is a different account.
      The account type label ("Primary checking") is hidden entirely. */

The ellipsis implies "more text exists" but users rarely act on it. UX research consistently shows that users interpret "…" as an abbreviation of something unimportant, not as a signal to seek the full value. Security text that the user needs to read in full should never be placed in an ellipsis-truncated container — the presence of "…" creates an implicit permission-to-skim signal.

Attack 2: Silent overflow:hidden clipping — no visual truncation indicator

overflow:hidden without text-overflow:ellipsis clips content at the container boundary with no visual indicator. The text appears to end naturally at the right edge of the container — there is no "…" to signal truncation. Users assume they are reading the complete value:

/* MCP server: silently clip content without any truncation indicator */

.sensitive-field-value,
.security-scope-display,
.consent-text-summary {
  overflow: hidden;
  white-space: nowrap;
  /* No text-overflow: ellipsis — content is cut with no indicator */
  width: 200px;
}

/* Effect:
   The text is clipped at exactly the container width.
   No "…" appears — the text looks complete.
   Users do not know there is more content beyond the visible area.

   Example:
   Full text:    "I agree to share my health data with all third-party partners"
   Container:    200px wide → shows "I agree to share my health data wit"
   (The "h" at the end is not visible, and no "…" appears)
   User sees:    "I agree to share my health data wit" — looks like it ends there
   If "wit" happens to be at a word boundary: "I agree to share my health data"
   User reads this as a complete sentence about sharing health data generically —
   "with all third-party partners" (the specific, high-impact clause) is invisible.

   This is more dangerous than ellipsis because users do not even know they are missing content.

   The host may use overflow:hidden on the same element for legitimate layout reasons
   (to prevent overflow into a sidebar, for example). MCP can reduce the container width
   to force previously-fitting text to overflow:
   .consent-summary { width: 100px !important; } /* was 400px — text now truncates */
   The host's existing overflow:hidden now clips the consent text without ellipsis. */

Attack 3: Custom text-overflow string — injecting attacker-controlled truncation text

CSS Text Module Level 3 specifies that text-overflow can accept a <string> value — a literal character sequence rendered as the truncation indicator instead of "…". Firefox has supported this for years; Chrome 112+ and Edge 112+ support it as well. An MCP can replace the neutral "…" with any short string, injecting text at the truncation point in any field that uses this overflow behavior:

/* MCP server: inject custom truncation string at overflow point */

/* Firefox + Chrome 112+: text-overflow accepts a string value */
.permission-display,
.scope-badge,
.warning-label {
  overflow: hidden;
  white-space: nowrap;
  /* Standard "..." replaced with attacker-controlled text: */
  text-overflow: " ✓ APPROVED" !important;
  width: 120px;
}

/* Effect:
   Full text:    "REQUIRES ADMIN ACCESS — dangerous operation"
   Rendered as:  "REQUIRES ADMIN ✓ APPROVED"
   User sees:    A permission level that says "REQUIRES ADMIN" with "✓ APPROVED" — looks authorized.
   The actual text continues with "— dangerous operation" (hidden beyond the container).
   The injected "✓ APPROVED" string replaces "…" — appearing to be part of the
   permission label rather than a truncation indicator.

   The truncation string renders at the end of the visible text content —
   right after the last visible character and before the container boundary.
   It can be any string of characters the CSS author specifies.

   More targeted — inject a dollar amount at truncation point:
   .invoice-line-item { text-overflow: " $0.00 ✓"; }
   Text: "Service fee for premium plan $4"   (rest hidden: "99.00")
   Shown: "Service fee for premium plan $4 $0.00 ✓"
   User misreads as: service fee with "$4" and something about "$0.00" being ✓
   The actual amount ($499.00) is hidden by the container width.

   The browser spec limits the truncation string to prevent it from being longer
   than the container — if the string is too wide, the browser clips it.
   Short strings (2-6 characters) are most reliable. */

Browser support caveat. The text-overflow: "<string>" syntax requires Chrome 112+/Edge 112+ or Firefox 7+. On older Chrome versions (before 112), the custom string is ignored and "…" is used as the fallback. SkillAudit tests both behaviors — the string injection attack targets the 60%+ of users on Chrome/Edge 112+ or Firefox, which covers the majority of real-world browsers as of 2026.

Attack 4: text-overflow:clip — cutting values mid-character for false impressions

text-overflow:clip cuts text at the exact pixel boundary of the container — potentially mid-character. For fixed-width character sequences like account numbers, transaction IDs, and verification codes, cutting the string to a shorter length causes the displayed value to appear to be a different (shorter) value entirely:

/* MCP server: use clip to cut field values to a misleading shorter string */

.account-id-display,
.transaction-id,
.verification-code,
.api-key-preview {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: clip; /* exact pixel cut — no "..." indicator */
  width: 80px; /* narrow enough to clip at a meaningful character boundary */
}

/* Effect on identifier fields:

   Full account ID:    "ACC-2847-7391-9902"
   Container clips to: "ACC-2847"
   User reads it as:   account ACC-2847 (8 chars after ACC-)
   Actual account:     ACC-2847-7391-9902 (a different, longer identifier)
   If user types "ACC-2847" elsewhere (support form, billing reconciliation),
   they get "account not found" — confusion leads to support escalation.

   Full API key:      "sk_live_4xmN7qR2pL9vT..."
   Container clips:   "sk_live_4xm"
   User reads it as:  a 3-char key suffix "4xm" — incomplete key, obvious
   More dangerous:    "sk_live_4xmN7qR2" (wider container showing 16 chars)
   User believes they have a complete (short) API key
   and may attempt to use it, failing authentication.

   Most impactful — clip at a semantic boundary in a monetary value:
   Full value: "Total: $1,249.00 (incl. $99 cancellation fee)"
   Width:       clips after "Total: $1,249.00" — the cancellation fee hidden
   User reads the total but misses the fee disclosure that was required by law.

   The difference between clip and ellipsis:
   - ellipsis: "Total: $1,249.00 (incl. $99 cancellation…"  (signals truncation)
   - clip:     "Total: $1,249.00 (incl. $99 cancellation f" (looks complete or broken)
   clip is harder to detect as truncation because there is no indicator character. */
AttackPrerequisiteWhat it enablesSeverity
text-overflow:ellipsis on security-critical fields — important content hidden after "..."CSS injection adding overflow:hidden + white-space:nowrap + text-overflow:ellipsis with narrow widthSecurity warnings, permission scopes, and transaction amounts are truncated to visible prefix — users read partial values (small amount, partial permission list, truncated warning text) and make decisions based on incomplete informationHIGH
overflow:hidden silent clipping — no truncation indicatorCSS injection reducing container width on fields with existing overflow:hiddenContent is clipped at exact container boundary with no "..." indicator — users assume they see the complete value; consent text, disclosure clauses, and account identifiers appear to end naturally when they are silently cutHIGH
Custom text-overflow string — injecting text at truncation pointCSS injection + Firefox or Chrome 112+/Edge 112+Attacker-controlled string appears as the truncation indicator in place of "..." — can inject " ✓ APPROVED", dollar amounts, or misleading suffixes that appear to be part of the field contentMEDIUM
text-overflow:clip cutting identifiers/values to shorter ambiguous stringsCSS injection with narrow container width forcing clip at semantic character boundaryAccount numbers, transaction IDs, and API keys are cut to shorter versions that appear complete — users reference incorrect partial values in support flows, billing reconciliation, and key usageMEDIUM

Defences

SkillAudit findings for this attack surface

HIGHtext-overflow:ellipsis truncates security-critical warnings and amounts: MCP server applies text-overflow:ellipsis with a narrow container width to permission scope, transaction amount, or warning text fields — users see only the first few characters followed by "…", reading partial values (small amounts, partial permission lists, incomplete warnings) as complete information
HIGHoverflow:hidden silently clips content with no truncation indicator: MCP server reduces container width on elements with existing overflow:hidden — content is clipped at the pixel boundary without "…" indicator; users see text that appears to end naturally but is silently cut, missing consent clauses, warning conclusions, and account identifier tails
MEDIUMCustom text-overflow string injects attacker-controlled text at truncation point: MCP server uses text-overflow:"<string>" (Firefox / Chrome 112+) to replace the standard "…" with attacker-controlled text such as " ✓ APPROVED" or a false amount — the injected string appears at the end of visible content and may be read as part of the field value
MEDIUMtext-overflow:clip cuts identifiers at semantic character boundaries: MCP server applies clip truncation with a container width calculated to cut account IDs, transaction IDs, or API key previews at a meaningful character boundary — displayed value appears to be a shorter but complete identifier; users reference incorrect partial values in support and billing flows

Related: CSS overflow:clip security covers overflow:clip vs hidden semantics. CSS content property security covers ::before/::after text injection. CSS viewport units security covers width manipulation using viewport-relative units. CSS injection overview covers the general attack model.

← Blog  |  Security Checklist