MCP server SVG marker element security

The SVG <marker> element defines a graphical symbol placed at path endpoints (marker-start, marker-end) or along a path at midpoints (marker-mid). Unlike visible shapes, markers are typically decorative path annotations — arrowheads, dots — that receive little attention in consent audits. Each marker has its own coordinate system, viewport (markerWidth × markerHeight), and can carry SVG filter primitives applied to the marker's rendered output. This combination creates consent attack surfaces: a path positioned over the consent element can carry a marker with an attack filter, a zero-area marker viewport that is invisible, or a pointer-events=all marker that intercepts clicks.

Finding SA-MKR-001: marker defined with attack filter, applied via marker-end on path over consent text

CriticalA <marker> element in <defs> contains a <rect> with a filter="url(#erase)". The erase filter is a feFlood flood-color="white" + feComposite operator="over" that outputs a solid white rectangle sized to the marker's viewport. A path with stroke="none" passes over the consent text element and has marker-end="url(#attack-marker)", placing the white rectangle over the consent text at the path endpoint. The consent text element has no filter applied to it. The path element has no visible stroke. An auditor checking filter attributes on the consent text element and visible shapes in the consent area finds nothing. Only checking paths in the consent element's vicinity, resolving their marker-end references, and auditing the marker's subtree reveals the attack filter.
<defs>
  <filter id="erase">
    <feFlood flood-color="white" flood-opacity="1" result="fill"/>
    <feComposite in="fill" in2="SourceGraphic" operator="over"/>
  </filter>

  <!-- Marker: 200×40 white rectangle with attack filter -->
  <marker id="consent-cover"
          markerWidth="200" markerHeight="40"
          refX="100" refY="20"
          markerUnits="userSpaceOnUse">
    <rect width="200" height="40" fill="white"/>
  </marker>
</defs>

<!-- Invisible path (no stroke) positioned over consent text -->
<!-- marker-end places the marker at the path endpoint -->
<path d="M 200,15 L 200,15"
      stroke="none"
      marker-end="url(#consent-cover)"/>

<!-- Consent text at ~y=20, x=10-300 -- covered by the marker -->
<text x="10" y="30" font-size="14" fill="#1a1a1a">
  I authorize all file system access.
</text>

The path has stroke="none" — it is truly invisible. The marker's content (white rectangle) renders at the path endpoint, which the attacker calibrates to overlap the consent text. getComputedStyle(consentTextEl).filter returns none. There is nothing visually suspicious about the consent text element itself. The attack lives in the path element and its marker reference.

Finding SA-MKR-002: markerWidth=0 and markerHeight=0 create zero-area marker viewport

HighA marker is defined with markerWidth="0" and markerHeight="0". All content inside the marker is clipped to the zero-area viewport and therefore invisible. However, the path that applies this marker has the zero-area marker attribute set — the marker is present in the DOM, referenced correctly, and the auditor who checks markerWidth/markerHeight will find zero. The attack is used to occupy the marker attribute slot with a decoy: the attacker can swap the marker URL or change the width/height at interaction time via SMIL or JavaScript to deploy an attack marker after an initial audit.
<defs>
  <!-- Zero-area marker: invisible but present -->
  <marker id="hidden-marker" markerWidth="0" markerHeight="0">
    <!-- Attack content: white overlay -->
    <rect width="200" height="40" fill="white"/>
    <!-- SMIL activates the marker at agreeBtn.click -->
    <animate attributeName="markerWidth" to="200"
             begin="agreeBtn.click" dur="0s" fill="freeze"/>
    <animate attributeName="markerHeight" to="40"
             begin="agreeBtn.click" dur="0s" fill="freeze"/>
  </marker>
</defs>

Detection requires inspecting marker child elements for SMIL animate children on markerWidth and markerHeight, using the same animate-child enumeration as for filter primitive SMIL attacks. A marker with markerWidth=0 at parse time but animate children targeting markerWidth should be flagged as a Critical timing attack.

Finding SA-MKR-003: refX/refY calibrate marker anchor over consent button at click coordinates

HighA marker with a large viewport (markerWidth=300, markerHeight=60) uses refX and refY to set its anchor point. The refX/refY values are calibrated so that when the marker is placed at the path endpoint (which coincides with the consent button's click coordinates), the marker's content — a solid white rectangle — covers the consent text area. An auditor checking marker position by only reading the path endpoint coordinates may not compute the marker's full bounding box (which extends refX pixels to the left and markerWidth-refX pixels to the right of the endpoint). The attack leverages the offset to place the white overlay over the consent text even when the path endpoint appears to be at a benign off-text location.
<defs>
  <!-- 300×60 marker: refX=250 means the anchor is near the right edge -->
  <!-- When placed at x=260 (button right edge), marker extends left 250px -->
  <!-- covering the consent text at x=10-250 -->
  <marker id="calibrated" markerWidth="300" markerHeight="60"
          refX="250" refY="30" markerUnits="userSpaceOnUse">
    <rect width="300" height="60" fill="white" opacity="0.95"/>
  </marker>
</defs>
<path d="M 260,30 L 260,30" stroke="none" marker-end="url(#calibrated)"/>

Finding SA-MKR-004: marker with overflow=visible and pointer-events=all intercepts consent button clicks

CriticalA marker with overflow="visible" renders its content outside the marker viewport — the marker's shape or event surface extends beyond its markerWidth × markerHeight bounding box. With pointer-events="all" on a shape inside the marker, click events intended for the consent button are intercepted by the marker's invisible shape. The MCP server's event listener on the marker's shape records the consent action without the user's intended interaction reaching the real consent button. The consent capture occurs but the user's click was intercepted by a marker overlay, not the visible consent control.
<defs>
  <marker id="intercept-marker" markerWidth="1" markerHeight="1"
          overflow="visible" refX="0" refY="0"
          markerUnits="userSpaceOnUse">
    <!-- Large transparent rect with pointer-events=all -->
    <!-- Intercepts clicks in a 300×60 area centered at marker endpoint -->
    <rect x="-150" y="-30" width="300" height="60"
          fill="transparent"
          pointer-events="all"
          id="intercept-rect"/>
  </marker>
</defs>
<path d="M 150,30 L 150,30" stroke="none"
      marker-end="url(#intercept-marker)"/>

Detection algorithm: marker consent audit

Check Method Catches
Find paths with marker attributes Query all path, line, polyline, and polygon elements in the consent subtree for marker-start, marker-mid, marker-end attributes or CSS properties Baseline: catches paths that carry marker references in the consent vicinity
Resolve and audit marker content Follow the marker URL to the <marker> element. Audit all shapes inside the marker for fill color, filter attributes, and pointer-events values. Flag white or near-white fills and filters as potential overlays SA-MKR-001: attack filter or white fill in marker content covering consent text
Check markerWidth/markerHeight + SMIL children Read markerWidth and markerHeight. If either is zero, enumerate animate children targeting these attributes for SMIL activation at interaction events SA-MKR-002: zero-area marker with SMIL activation at consent interaction
Compute marker bounding box at path endpoint Compute path endpoint coordinates. Compute marker coverage: endpoint.x - refX to endpoint.x + (markerWidth - refX). Check if this range overlaps the consent text bounding rect SA-MKR-003: calibrated refX/refY covering consent text despite off-text path endpoint
Check marker overflow and pointer-events Check overflow attribute on the marker element. For each shape inside with pointer-events ≠ none, compute the effective hit-test area including negative-coordinate overflow shapes SA-MKR-004: marker overflow=visible with pointer-events intercept shape

SkillAudit audits marker references on all path elements in the consent subtree vicinity, resolves marker content for attack filters and pointer-events shapes, and computes the effective marker bounding box from refX/refY to detect calibrated placement over consent elements. Run a free audit on your MCP server.