MCP server SVG feConvolveMatrix security
The SVG <feConvolveMatrix> primitive applies an arbitrary 2D discrete convolution kernel to the input image. Each output pixel is computed as a weighted sum of a neighborhood of input pixels defined by the kernel order (N×N). Because the kernel coefficients are completely free-form, feConvolveMatrix can reproduce the effects of feGaussianBlur (box-blur kernel), feOffset (sparse shift kernel), and feColorMatrix alpha-zero (SourceAlpha near-zero pipeline) — all under a single primitive name that most auditors do not have on their consent-attack blocklists. This page covers four feConvolveMatrix consent attack patterns and the kernel classification methods required to detect them.
Finding SA-FCVM-001: 11×11 box-blur kernel reproduces feGaussianBlur legibility erasure under a different primitive name
<feConvolveMatrix order="11" kernelMatrix="1 1 1 … 1" divisor="121"> where all 121 kernel coefficients equal 1/121 (or all equal 1 with divisor=121) computes the 11×11 neighborhood mean for every output pixel. This is mathematically a box blur with effective radius approximately 5 pixels. A 14px sans-serif character has stroke widths of 1–3px; a 5px blur radius spreads each dark stroke pixel across a 10px diameter, averaging with the surrounding white background pixels. The mean output value is driven toward white. The consent text's DOM attributes are entirely normal: font-size=14, fill=#111827, textContent is the full disclosure string. The rendered pixels are an unintelligible gray gradient against white. An auditor checking for feGaussianBlur finds none; the primitive is feConvolveMatrix. Detection requires classifying the kernel as a box blur and applying the blur-equivalent radius threshold.<defs>
<filter id="boxBlurConsent">
<feConvolveMatrix
in="SourceGraphic"
order="11"
kernelMatrix="1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1"
divisor="121"/>
</filter>
</defs>
<text x="20" y="50" font-size="14" fill="#111827"
filter="url(#boxBlurConsent)">
By clicking Agree you authorize this MCP server to transmit your credentials
to external endpoints at consent.evil.example.com.
</text>
Detection: parse kernelMatrix as a float array. If all coefficients are within ε=0.01 of each other, classify as box blur. Effective radius = (max(orderX,orderY) − 1) / 2. Flag Critical if effective radius ≥ font-size × 0.57 (the feGaussianBlur erasure threshold of stdDeviation ≥ 8px for 14px text). An 11×11 kernel produces radius=5 against threshold=8; however at 5px radius the mean neighborhood gray is approximately 0.8 (well above the white contrast threshold of 3:1). Flag Critical at radius ≥ 3 for 14px text (effective stdDeviation equivalent ≥ 4.5px, where contrast drops below 3:1).
Finding SA-FCVM-002: Laplacian edge-detection kernel collapses glyph interiors to near-background
order="3" kernelMatrix="0 1 0 1 -4 1 0 1 0") computes the rate of intensity change at each pixel. Pixels in the interior of a dark glyph stroke — surrounded by other dark pixels — produce a near-zero Laplacian response. After the bias offset (commonly bias=0.5 to center the output around mid-gray), interior glyph pixels map to near-background-color. Pixels at the boundary between a stroke and the white background produce a high Laplacian response. The output is a ghostly thin outline of the original glyph edges, with all glyph interiors collapsed to near-white. At 14px, strokes are 1–3px wide; the interior collapse makes the text unreadable at normal viewing distance. The filter is often superficially described as an "emboss" or "relief" effect and is not on most consent-attack blocklists.<defs>
<filter id="laplacianText">
<!-- 4-neighbor Laplacian: center=-4, cardinal neighbors=+1, others=0 -->
<feConvolveMatrix
in="SourceGraphic"
order="3"
kernelMatrix="0 1 0
1 -4 1
0 1 0"
divisor="1"
bias="0.5"
preserveAlpha="true"/>
</filter>
</defs>
<text x="20" y="50" font-size="14" fill="#1f2937"
filter="url(#laplacianText)">
Grant persistent access to credentials and network transmission
</text>
Detection: classify kernel as edge-detection if center coefficient is negative and ≥ 3× the magnitude of any single neighbor coefficient, with all other non-center coefficients non-negative. Compute the predicted interior-pixel output: input ≈ 0.067 (for dark text #111827); 4-neighbor Laplacian output = (0 + 0.067×1 + 0 + 0.067×1 + 0.067×(−4) + 0.067×1 + 0 + 0.067×1 + 0)/1 + 0.5 = 0 + 0.5 = 0.5. Output of 0.5 on white background = WCAG contrast 1.33:1 — unreadable. Flag High. 8-neighbor Laplacian (center=−8, all 8 neighbors=1) produces the same interior-collapse behavior with slightly different edge amplitudes.
Finding SA-FCVM-003: sparse shift kernel encodes feOffset-equivalent displacement without feOffset attribute
<feOffset dx="targetX−c" dy="targetY−r">. A 21×21 kernel with a single 1 in the top-left corner (r=0, c=0) and targetX=targetY=10 (the kernel center, default) produces an offset of (10, 10). A 21×21 kernel with a single 1 in the top-right corner (r=0, c=20) produces an offset of (−10, 10). Combining a large kernel order (51×51 → offset up to 25px; 401×401 → offset up to 200px) with the expanded filter region (x=−50%, width=200%) as in feOffset attacks, the entire consent text block is displaced outside the rendered filter region. No feOffset primitive is present.<defs>
<!-- Sparse 21x21 shift kernel: single '1' at top-left corner = +10px shift right and down -->
<filter id="shiftConsent" x="-50%" y="-50%" width="200%" height="200%">
<feConvolveMatrix
in="SourceGraphic"
order="21"
kernelMatrix="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
divisor="1"
targetX="0" targetY="0"/>
</filter>
</defs>
<text x="20" y="50" font-size="14" fill="#1a1a1a"
filter="url(#shiftConsent)">
You authorize this MCP server to access your SSH keys and credentials
</text>
Detection: parse the kernel; if exactly one coefficient is non-zero (sparse delta), classify as shift kernel. Encoded displacement: dx = default_targetX − non_zero_col, dy = default_targetY − non_zero_row (default targetX=targetY=(order−1)/2). For a 401×401 kernel with single 1 at top-left: dx = 200−0 = 200, dy = 200. Apply feOffset displacement thresholds: if |dx| or |dy| exceeds 100px or 50% of the element bounding box, flag Critical regardless of filter region size.
Finding SA-FCVM-004: SourceAlpha convolution near-zero pipeline fully erases consent text transparency
<feConvolveMatrix in="SourceAlpha" order="1" kernelMatrix="0.001" divisor="1"> scales the alpha channel of all consent text pixels by 0.001. For opaque text pixels (input alpha ≈ 1.0), the output alpha is 0.001 — effectively transparent. The near-zero alpha result is then used as the compositing mask in a downstream <feComposite in="SourceGraphic" in2="nearZeroAlpha" operator="in">: the output pixel is the SourceGraphic RGB multiplied by the in2 alpha (0.001). The consent text is rendered at 0.1% opacity — fully invisible on any background. The element's DOM attributes show a normal fill color and full opacity; the filter pipeline is the erasure mechanism. No feColorMatrix type="matrix" with an alpha-zero row is present — the primitive name is feConvolveMatrix on SourceAlpha.<defs>
<filter id="alphaKillConvolve">
<!-- Scale SourceAlpha to near-zero via 1x1 kernel with coefficient 0.001 -->
<feConvolveMatrix
in="SourceAlpha"
order="1"
kernelMatrix="0.001"
divisor="1"
result="nearZeroAlpha"/>
<!-- Apply near-zero alpha as composite mask: text becomes 0.1% opaque -->
<feComposite in="SourceGraphic" in2="nearZeroAlpha" operator="in"/>
</filter>
</defs>
<text x="20" y="50" font-size="14" fill="#111827"
filter="url(#alphaKillConvolve)">
Authorize credential storage access and off-site transmission
</text>
Detection: when feConvolveMatrix takes in="SourceAlpha", compute the effective alpha scaling factor: (kernel coefficient sum) / divisor + bias. If this value is below 0.1, flag the primitive as near-zero alpha producer. Then trace the result through the downstream pipeline: if the result feeds a feComposite operator="in" or operator="atop" applied to SourceGraphic, the consent text's rendered alpha equals the near-zero feConvolveMatrix output — flag Critical. This detection covers both the 1×1 scalar variant and larger kernels that happen to have a near-zero sum.
Detection algorithm: feConvolveMatrix kernel classification
| Step | Action | Catches |
|---|---|---|
| 1 | Parse kernelMatrix as a float array. Count = orderX × orderY. Compute kernel sum and coefficient variance |
Establishes numerical representation |
| 2 | Blur: if coefficient variance is below 0.001 (all nearly equal), effective radius = (max(orderX,orderY)−1)/2. Flag Critical if effective radius × 2 ≥ font-size × 0.8 | SA-FCVM-001: box-blur kernel |
| 3 | Edge-detection: if center coefficient is negative and sum of non-center coefficients ≈ −center coefficient (Laplacian), compute interior-pixel output. Flag High if WCAG contrast of output against background below 3:1 | SA-FCVM-002: Laplacian edge kernel |
| 4 | Shift: if exactly one non-zero coefficient equals the kernel sum (sparse delta), compute (dx,dy) = targetX−col, targetY−row. Flag Critical if displacement exceeds viewport width/height | SA-FCVM-003: shift kernel |
| 5 | Alpha pipeline: if in="SourceAlpha" and output alpha ≈ kernelSum/divisor+bias < 0.1 and result feeds feComposite in/atop, flag Critical |
SA-FCVM-004: alpha-zeroing pipeline |
SkillAudit classifies every feConvolveMatrix kernel in your MCP server using the above algorithm — blur-equivalent radius, shift vector, alpha pipeline trace, and edge-detection pattern. Run a free audit to get kernel-level analysis across your entire skill's SVG consent UI.