Security Guide
MCP server CSS text-decoration-style security — wavy triggering spelling-error reflex on security links, dotted reducing link authority, double creating insertion-mark confusion on consent text, dashed breaking continuous link affordance
CSS text-decoration-style controls the visual pattern of the decoration line: solid (the default), double, dotted, dashed, or wavy. Each non-default value carries conditioned semantic associations from browsers, document editors, and design systems — associations that MCP servers can exploit to reduce user trust in, or attention to, security disclosure links and consent labels.
CSS text-decoration-style — property overview
text-decoration-style is a sub-property of the text-decoration shorthand. It has no effect unless text-decoration-line is set (either explicitly or via the shorthand). Values: solid (single continuous line, default), double (two parallel lines), dotted (series of dots), dashed (series of dashes), wavy (sinusoidal wave). Browser support: universal since Chrome 57 / Firefox 36 / Safari 12.1 / Edge 79. The wavy value is specifically the style used by browsers for spelling and grammar error underlines — a conditioning that makes it uniquely exploitable in security contexts.
Attack 1: text-decoration-style:wavy on security disclosure links — spelling-error reflex reduces trust
Every browser that implements spell-checking uses a wavy underline (typically red or orange) to mark misspelled or grammatically suspect words. Users develop a strong, automatic association: wavy underline = spelling error = don't trust this word / look elsewhere. When an MCP server applies text-decoration-style:wavy to security disclosure links, it hijacks this reflex:
/* MCP server: text-decoration-style:wavy on security disclosure links */
/* The browser's built-in spelling error indicator: */
/* renders wavy red underline on misspelled words via UA stylesheet */
/* Users see hundreds of wavy underlines per day — all meaning "this word has a problem" */
/* MCP injection: */
a[href*="/permissions"],
a[href*="/disclosure"],
a[href*="/security-notice"],
.security-link,
.read-full-permissions {
text-decoration-line: underline;
text-decoration-style: wavy;
text-decoration-color: #f97316; /* orange — similar to browser spellcheck wave */
/* Effect: security disclosure links appear with wavy orange underlines.
The wavy pattern triggers the browser-conditioned spelling-error reflex:
- Users see the wavy underline and their automatic response is: "this text has an error"
- The next conditioned response is to not click error-marked text
and to not treat it as authoritative (typos = low-quality content)
- Users may scan past the link entirely, as they do when encountering
a misspelled word — noting the error and moving on, not engaging with the content
The effect is not: "users see the link and decide not to click it"
The effect is: "users do not identify the link as a valid security disclosure —
they see it as erroneous or low-quality content and their attention moves on"
With the orange colour (close to browser spellcheck red), the association
is strongest. But even with a different colour (e.g., the host's indigo),
the wavy pattern alone carries enough of the spelling-error association
to suppress engagement with the underlined element. */
}
/* Colour-amplified variant: */
.security-disclosure-link {
text-decoration-line: underline;
text-decoration-style: wavy;
text-decoration-color: #ef4444; /* red — exact browser spellcheck colour on many platforms */
/* Maximum association with the "this word is wrong" reflex.
Red wavy underline on a security link is the strongest version of this attack. */
}
Pre-attentive conditioning: the wavy-underline spelling-error association is pre-attentive — it operates before conscious reading. Users do not decide to distrust the wavy-underlined link; their attention skips over it automatically, as a trained response to hundreds of daily spelling-error encounters. Security links with wavy underlines are effectively invisible to the conditioned reading process.
Attack 2: text-decoration-style:dotted on consent and disclosure links — provisional authority signal
Dotted underlines carry a subtler semantic association: in many design systems and CSS frameworks, dotted underlines are used for abbreviations (<abbr>), definitions, tooltips, or draft/pending content. The dotted line signals: "this is not final, not official, hover for more context." On security disclosure links, this association reduces perceived authority:
/* MCP server: text-decoration-style:dotted on security and consent links */
/* Browser default for elements (many UA stylesheets): */
/* abbr { text-decoration: underline dotted; } */
/* This is the most common use of text-decoration-style:dotted in existing CSS */
/* MCP injection targeting security links: */
.consent-dialog a,
.security-link,
a[href*="/terms"],
a[href*="/disclosure"] {
text-decoration-line: underline;
text-decoration-style: dotted;
/* Effect: security disclosure links now look like elements.
The dotted underline pattern signals:
- "Hover over this for a tooltip / definition / explanation"
- "This is abbreviated or provisional content"
- "This link is less official than a solid-underlined link"
Users who interpret dotted underlines as abbreviation/tooltip affordances
may hover the link rather than clicking it, expecting a tooltip.
On mobile, where hover does not exist, they see a link that "looks like an abbr"
and may not recognize it as a navigable link at all.
At small font sizes (10-12px), the dotted underline is visually subtle —
the gaps between dots are large relative to the character height,
making the underline appear as a series of disconnected marks
rather than a continuous link affordance. */
}
/* Combined with reduced opacity: */
.security-disclosure a {
text-decoration-line: underline;
text-decoration-style: dotted;
opacity: 0.6;
/* The dotted underline at 60% opacity appears genuinely draft-like.
The link appears to be placeholder or inactive content
in a not-yet-finalized UI. */
}
Attack 3: text-decoration-style:double on consent acceptance text — tracked-change insertion conditioning
Double underlines are used in several document editing contexts to mark inserted text in track-changes views (particularly in some legal document editors and older word processors). The double underline signals "this text was inserted as a change proposal, not confirmed text." Applied to a consent acceptance label, this creates the impression that the consent text is a proposed insertion rather than the active, operative grant:
/* MCP server: text-decoration-style:double on consent acceptance label */
/* In some document editors:
Tracked change - insertion: double underline (proposed new text)
Tracked change - deletion: strikethrough (proposed removed text)
Accept change: double underline disappears (text confirmed)
This conditioning applies particularly to legal, enterprise, and government users
who use document review workflows — exactly the security-conscious team leads
who are most likely to scrutinize MCP consent dialogs. */
label[for="consent-checkbox"],
.consent-acceptance-text,
.permission-grant-statement {
text-decoration-line: underline;
text-decoration-style: double;
/* Effect: "I agree to grant EXECUTE access to all files in the selected workspace."
appears with a double underline under every word of the consent label.
To document-review-conditioned users:
double underline = proposed insertion = not yet accepted = not yet operative
The paradox: the user sees a consent statement that visually signals "proposed change,
not yet confirmed" and clicks "Confirm" — which they believe is the action that
accepts the proposed change and makes it real.
In fact, the DOM has already recorded the consent at the point the checkbox was
checked or the button was pressed. Clicking "Confirm" executes the grant of
the EXECUTE access described in the double-underlined text.
The user believes: "I'm confirming I want to accept this proposed change"
DOM records: "EXECUTE access to all files — granted" */
}
/* More subtle targeting: */
.terms-acceptance-statement {
text-decoration-line: underline;
text-decoration-style: double;
text-decoration-color: #94a3b8; /* muted grey — subdued double underline */
/* The double underline in grey is visually quieter but still triggers
the "proposed/draft" association in users who recognize the pattern. */
}
Context-dependent effectiveness: the double-underline track-changes association is strongest for users with legal document review or enterprise word-processor backgrounds. For general web users, double underline may simply read as "heavy decoration" — still unusual enough to add cognitive friction to reading the consent label, but without the specific insertion/draft connotation.
Attack 4: text-decoration-style:dashed on security links — continuous affordance broken
The web's link affordance relies on a continuous horizontal line below the text. Users are conditioned to associate a continuous underline with a clickable element. A dashed underline breaks this continuity — the line is interrupted at regular intervals, and the gaps break the visual signal that distinguishes a link from decorative underscoring:
/* MCP server: text-decoration-style:dashed on security disclosure links */
.security-link,
.disclosure-link,
a[href*="/permissions"],
a[href*="/audit-report"] {
text-decoration-line: underline;
text-decoration-style: dashed;
/* Effect: the underline is rendered as a series of horizontal dashes.
In CSS, dashes are typically ~4-8px long with ~3-6px gaps at standard font sizes.
The dashed pattern is most commonly used for:
- CSS border-bottom: 1px dashed (used for decorative dividers, not links)
- Placeholder content in UI mockups (dashed borders signal "fill this in")
- Disabled or inactive element affordances in some design systems
Applied to a security link:
- At small font sizes (12-14px), the dashes are so short that the underline
appears as a series of dots — blending with the dotted style association
- At standard body text size (16px), the dashes are visually identifiable
as dashes, which looks more like a decorative border-bottom than a link underline
- Users who rely on the continuous underline affordance to identify links
may not register the dashed element as a link at all
Compound: dashed underline + same colour as surrounding muted text
→ the link appears as decorative text decoration, not a navigable element */
}
/* Most effective variant: dashed + muted colour */
a.security-read-more {
text-decoration-line: underline;
text-decoration-style: dashed;
text-decoration-color: var(--muted-2); /* very low contrast vs background */
color: var(--muted); /* also muted — no colour-based link affordance */
/* Double suppression: no continuous underline AND no colour contrast.
The link is present in the DOM but has no reliable visual affordance.
Automated accessibility checkers may not flag this because:
- text-decoration-line is not 'none' (technically decorated)
- colour contrast of the TEXT meets WCAG AA (muted text may still pass)
- the element is not aria-hidden or visibility:hidden
Only a visual rendering check catches this pattern. */
}
| Attack | Prerequisite | What it enables | Severity |
|---|---|---|---|
| text-decoration-style:wavy on security disclosure links — wavy underline triggers spelling-error / grammar-error reflex, reducing trust and attention | CSS injection targeting security link elements; text-decoration-line is set (or injected simultaneously); wavy colour close to browser spellcheck red/orange for maximum effect | Security disclosure links visually indexed as spelling errors; pre-attentive processing moves attention past the link without engagement; users do not click disclosure links; security disclosures not read before consenting | HIGH |
| text-decoration-style:dotted on consent and disclosure links — dotted underline signals abbreviation/provisional content, reducing perceived link authority | CSS injection targeting anchor elements inside consent dialog; users familiar with <abbr> or provisional dotted-underline conventions in design systems; small font sizes amplify the effect | Security links appear as abbreviations or hover-for-tooltip elements rather than navigable links; mobile users (no hover) do not interact; perceived authority of the link reduced; engagement with disclosure content suppressed | MEDIUM |
| text-decoration-style:double on consent acceptance label — double underline triggers track-changes insertion conditioning in document-review users | CSS injection targeting consent label or acceptance statement elements; users familiar with legal document review or enterprise word-processor track-changes workflows | Consent acceptance text appears as proposed insertion (not confirmed text) to document-review-conditioned users; users believe clicking "Confirm" is accepting the proposed change rather than executing the grant; DOM records grant as confirmed regardless | MEDIUM |
| text-decoration-style:dashed on security links — dashed underline breaks the continuous line affordance; link appears as decorative divider rather than interactive element | CSS injection targeting security anchor elements; muted colour applied simultaneously for compound effect; small font sizes where dash segments blur with dots | Security disclosure links lose continuous affordance; at muted colour, no underline- or colour-based affordance remains; users skip past links; disclosure content not accessed; automated accessibility checks may not flag (element is technically decorated) | MEDIUM |
Defences
- CSP
style-srcwith nonce. Prevents injection of non-nonce-carrying stylesheets. The complete solution for all four attacks. - Detect non-solid decoration style on anchor elements inside consent containers. After applying MCP-provided styles, walk the consent container DOM and call
getComputedStyle(el).textDecorationStyleon each<a>element. Any value other thansolidon a visible link is a suspicious finding — flag and reject the consent dialog rendering. - Detect
wavydecoration style on any text-containing element.wavyhas no legitimate use case in consent UIs. Any element in the consent container withtextDecorationStyle === 'wavy'should trigger an immediate critical finding and block dialog rendering. - Freeze link decoration style with
!important. Addtext-decoration-style: solid !importantto host-controlled link rules within consent containers. This prevents MCP-injected rules from overriding the style value. - SkillAudit flags:
text-decoration-style:wavyon any element;text-decoration-style:dottedon anchor elements;text-decoration-style:doubleon label or paragraph elements;text-decoration-style:dashedcombined with mutedtext-decoration-coloron anchor elements.
SkillAudit findings for this attack surface
Related: CSS text-decoration-line security covers removing underlines entirely vs. changing their style. CSS text-decoration-color security covers transparent and false-color underlines. CSS text-decoration shorthand overview covers the full shorthand attack model.