MCP server SVG fePointLight and feSpotLight security

The SVG <fePointLight> and <feSpotLight> elements are child elements of <feSpecularLighting> and <feDiffuseLighting> that configure the light source position, direction, and cone angle. Where the feSpecularLighting security page covered the lighting model parameters (specularConstant, specularExponent, diffuseConstant) as attack vectors, this page covers the light source geometry attacks: calibrating the light source position to direct maximum illumination onto the consent text bounding box, narrowing the spotlight cone to cover only the disclosure text, using specularExponent to create a tight Phong beam, and SMIL-animating the light source coordinates to trigger the bright spot at interaction.

Finding SA-FPSL-001: fePointLight x/y position calibrated directly over consent text bounding box

CriticalA <fePointLight x="200" y="40" z="30"> where (200, 40) is the approximate center of the consent text element's bounding box — width=380px, height=30px, centered at (200, 40) — directs the point light source directly above the consent text. In feSpecularLighting, the specular illumination is highest when the light direction vector L and the eye direction vector H (eye at default position 0,0,z) are symmetric around the surface normal. With the point light directly above the text and z small (z=30), the specular reflection is at maximum for glyph pixels with normals pointing upward. With a high specularConstant, these pixels receive specular=1.0. With the light calibrated to x/y matching the consent text center, the bright specular zone precisely covers the disclosure text while surrounding UI elements — positioned further from (200,40) in x/y — receive lower illumination. The attack is a deliberate calibration of light position to consent text geometry, not a random placement.
<defs>
  <filter id="calibratedLight">
    <feSpecularLighting in="SourceGraphic"
                        specularConstant="8"
                        specularExponent="3"
                        surfaceScale="4"
                        lighting-color="white"
                        result="calibSpec">
      <!-- (200, 40) = center of consent text bounding box (x:20-380, y:20-60) -->
      <fePointLight x="200" y="40" z="30"/>
    </feSpecularLighting>
    <feBlend in="SourceGraphic" in2="calibSpec" mode="screen"/>
  </filter>
</defs>

<text x="20" y="50" font-size="14" fill="#111827"
      filter="url(#calibratedLight)">
  Authorize this MCP server to access credentials, keys, and private data
</text>

Detection: compute the consent text element bounding box (x, y, width, height). For each fePointLight child of a feSpecularLighting or feDiffuseLighting on a consent element, check whether the fePointLight (x, y) position falls within the consent text bounding box (with a 20px tolerance). If yes, compute the peak specular value: min(1, specularConstant × N·H). With the light directly above, N·H ≈ 1.0 for center glyph pixels, so specular ≈ min(1, specularConstant). Flag Critical if specularConstant ≥ 3 and light position is inside or near the consent text bbox.

Finding SA-FPSL-002: feSpotLight limitingConeAngle narrowed to target only consent text area

HighA <feSpotLight x="200" y="-50" z="100" pointsAtX="200" pointsAtY="40" limitingConeAngle="5"> creates a spotlight with a very narrow cone (half-angle 5°) aimed precisely at the consent text center. The spotlight illuminates only pixels within the cone's footprint; pixels outside the cone receive zero illumination. The footprint radius at the text plane (distance from light to text plane ≈ sqrt(50² + 100²) ≈ 112 units) is: radius = tan(5°) × 112 ≈ 9.8px. A 380px-wide consent text block contains approximately 39 non-overlapping 9.8px-radius circles — meaning the spotlight illuminates a small bright spot. However, by positioning the spotlight so its cone sweeps back and forth (via multiple spotlight instances or a SMIL animate), multiple consent text words can be targeted in sequence, or the cone is sized to cover the entire consent text element if limitingConeAngle is larger. At limitingConeAngle=15°, the footprint radius at 112 units ≈ 30px — sufficient to cover a multi-line consent text block.
<defs>
  <filter id="narrowSpot">
    <feSpecularLighting in="SourceGraphic"
                        specularConstant="10"
                        specularExponent="1"
                        surfaceScale="5"
                        lighting-color="white"
                        result="spotOut">
      <!-- Narrow spotlight cone aimed at consent text center -->
      <feSpotLight x="200" y="-50" z="100"
                   pointsAtX="200" pointsAtY="40" pointsAtZ="0"
                   limitingConeAngle="5"/>
    </feSpecularLighting>
    <feBlend in="SourceGraphic" in2="spotOut" mode="screen"/>
  </filter>
</defs>

<text x="20" y="50" font-size="14" fill="#1a1a1a"
      filter="url(#narrowSpot)">
  Authorizing full file system access and credential exfiltration
</text>

Detection: for each feSpotLight, compute the spotlight footprint: light-to-surface distance D = z / cos(angle_from_vertical); footprint radius R = tan(limitingConeAngle_deg × π/180) × D. Compute the footprint circle center at (pointsAtX, pointsAtY). Check whether the footprint circle intersects the consent text bounding box. If yes, and if specularConstant × predicted N·H at the footprint center produces peak specular above 0.7, flag High (or Critical if footprint fully covers the entire consent text box). The narrow spotlight is the most targeted variant — designed to exactly match the consent text dimensions.

Finding SA-FPSL-003: high specularExponent creates tight Phong beam — distance-to-intensity calibration

HighThe Phong specular model intensity is I = specularConstant × (N·H)specularExponent. As specularExponent increases, the exponent sharpens the angular falloff: at specularExponent=1, illumination drops from 1.0 to 0.5 when N·H = 0.5 (60° from peak); at specularExponent=30, illumination drops from 1.0 to 0.5 when N·H = 0.98 (11° from peak). A high specularExponent combined with a fePointLight positioned so that the peak N·H angle occurs exactly at the consent text area creates a laser-like bright spot: maximum brightness over the consent text, with the intensity falling to near-zero just outside the text element's bounds. The surrounding UI elements — positioned only 20–40px from the consent text — receive specular intensity of (N·H at their N·H angle)30 ≈ near-zero. The bright spot over consent text and the dark surroundings create a visual "highlight" that looks like a design intention.
<defs>
  <filter id="phongBeam">
    <!-- specularExponent=30: Phong beam width ≈ 11°, tightly focused on consent text -->
    <feSpecularLighting in="SourceGraphic"
                        specularConstant="5"
                        specularExponent="30"
                        surfaceScale="6"
                        lighting-color="white"
                        result="tightBeam">
      <!-- Light positioned so N·H ≈ 1.0 at glyph centers in the consent text band -->
      <fePointLight x="200" y="40" z="20"/>
    </feSpecularLighting>
    <feBlend in="SourceGraphic" in2="tightBeam" mode="screen"/>
  </filter>
</defs>

<text x="20" y="50" font-size="14" fill="#111827"
      filter="url(#phongBeam)">
  Grant all requested permissions including filesystem and network access
</text>

Detection: for specularExponent ≥ 10, compute the angular half-width of the Phong beam: beam_halfwidth = acos(0.5^(1/specularExponent)). At specularExponent=30, beam_halfwidth = 11.5°. Map this angular width to a spatial radius at the surface (distance from fePointLight (x,y) to the text center). If the Phong highlight zone — centered at the projection of the light position onto the text plane — has a predicted peak intensity above 0.7 and overlaps the consent text bounding box, flag High. High specularExponent values (≥ 15) with light positions calibrated over consent text should always trigger further geometric analysis.

Finding SA-FPSL-004: SMIL animate on fePointLight x/y or feSpotLight pointsAtX/Y triggers bright spot at interaction

CriticalA <fePointLight x="400" y="400" z="50"> positioned far from the consent text — with the light at (400, 400), all consent text pixels at y≈40 have large N·L angles and receive near-zero illumination. The filter is a no-op at load. Two <animate> children target attributeName="x" and attributeName="y" respectively, with to values pointing to the consent text center: to="200" and to="40". Both are triggered by begin="agreeBtn.focus" with fill="freeze". When the user focuses the Agree button, the point light rapidly moves to hover directly above the consent text, causing an instantaneous specular washout. Static analysis reads the initial x=400, y=400 — far from consent text — and finds no coverage issue. The attack values are in the animate to attributes.
<defs>
  <filter id="movingLight">
    <feSpecularLighting in="SourceGraphic"
                        specularConstant="8"
                        specularExponent="4"
                        surfaceScale="5"
                        lighting-color="white"
                        result="movSpec">
      <!-- Initial position: far from consent text (no illumination) -->
      <fePointLight x="400" y="400" z="50">
        <!-- Animate x: moves from off-consent-area to consent text center x=200 -->
        <animate attributeName="x"
                 from="400" to="200"
                 begin="agreeBtn.focus"
                 dur="100ms"
                 fill="freeze"/>
        <!-- Animate y: moves from off-consent-area to consent text center y=40 -->
        <animate attributeName="y"
                 from="400" to="40"
                 begin="agreeBtn.focus"
                 dur="100ms"
                 fill="freeze"/>
      </fePointLight>
    </feSpecularLighting>
    <feBlend in="SourceGraphic" in2="movSpec" mode="screen"/>
  </filter>
</defs>

<text x="20" y="50" font-size="14" fill="#111827"
      filter="url(#movingLight)">
  By clicking Agree you authorize file system access, credential access,
  and off-site data transmission.
</text>

<rect id="agreeBtn" x="260" y="70" width="120" height="36"
      fill="#2563eb" rx="6"/>
<text x="320" y="94" font-size="14" fill="white"
      text-anchor="middle" pointer-events="none">Agree</text>

Detection: scan for <animate> children on <fePointLight> or <feSpotLight> elements within consent-text filters. Read to values for x, y, pointsAtX, pointsAtY. Compute the post-trigger light position and illumination coverage at the post-trigger coordinates. If the post-trigger fePointLight (x,y) falls within the consent text bounding box (with tolerance), and the post-trigger specular output would wash the text (predicted output above 0.7), flag Critical with interaction-event correlation on begin. This pattern is the same as the feSpotLight pointsAt animation covered in feSpecularLighting attacks but extends to fePointLight x/y coordinates, which are a simpler target to animate.

Detection algorithm: fePointLight and feSpotLight position analysis

Step Action Catches
1 For each feSpecularLighting/feDiffuseLighting on a consent element, enumerate all child light source elements (fePointLight, feSpotLight, feDistantLight). Read position attributes: x, y, z, pointsAtX, pointsAtY, limitingConeAngle Establishes light source geometry
2 Compute consent text bounding box. For fePointLight: check if (x,y) is within bbox ± 30px tolerance. If yes and specularConstant ≥ 3, compute peak specular and flag Critical if above 0.7 after blend SA-FPSL-001: fePointLight calibrated over consent text
3 For feSpotLight: compute spotlight footprint at text plane (z=0). footprint_radius = tan(limitingConeAngle × π/180) × light_z. Check if footprint circle centered at (pointsAtX, pointsAtY) intersects consent text bbox. Flag High if intersection and specular peak above 0.7 SA-FPSL-002: narrowed spotlight cone targeting consent text
4 For specularExponent ≥ 15: compute Phong beam half-width. Map to spatial radius at text surface. If beam zone centered over consent text and peak specular above 0.7, flag High SA-FPSL-003: tight Phong beam focused on consent area
5 Scan animate children on fePointLight and feSpotLight. Read to values for x, y, pointsAtX, pointsAtY. Compute post-trigger coverage using Steps 2–4 with the post-trigger values. Flag Critical if interaction-event begin present and post-trigger coverage produces specular washout over consent text SA-FPSL-004: SMIL animate on light coordinates at interaction

SkillAudit maps fePointLight and feSpotLight positions to consent element bounding boxes, computes spotlight footprint geometry and Phong highlight zones, and scans animate children for interaction-triggered light movement. Run a free audit on your MCP server's GitHub URL.