Skip to content

Commit ed33c68

Browse files
authored
Merge pull request #1635 from HackTricks-wiki/update_SVG_Filters_-_Clickjacking_2_0_20251205_015403
SVG Filters - Clickjacking 2.0
2 parents ffcbf7d + a87aa05 commit ed33c68

File tree

1 file changed

+71
-4
lines changed

1 file changed

+71
-4
lines changed

src/pentesting-web/clickjacking.md

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,81 @@ A code example can be found in [this page](https://www.paulosyibelo.com/2024/12/
112112
> [!WARNING]
113113
> This technique allows to trick the user to click on 1 place in the victim page bypassing every protection against clickjacking. So the attacker needs to find **sensitive actions that can be done with just 1 click, like OAuth prompts accepting permissions**.
114114

115+
### SVG Filters / Cross-Origin Iframe UI Redressing
116+
117+
Modern Chromium/WebKit/Gecko builds let CSS `filter:url(#id)` be applied to cross-origin iframes. The iframe’s rasterized pixels are exposed to the SVG filter graph as `SourceGraphic`, so primitives such as `feDisplacementMap`, `feBlend`, `feComposite`, `feColorMatrix`, `feTile`, `feMorphology`, etc. can arbitrarily warp the victim UI before the user sees it, even though the attacker never touches the DOM. A simple Liquid-Glass style filter looks like:
118+
119+
```html
120+
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
121+
```
122+
123+
* Useful primitives: `feImage` loads attacker bitmaps (e.g., overlays, displacement maps); `feFlood` builds constant-color mattes; `feOffset/feGaussianBlur` refine highlights; `feDisplacementMap` refracts/warps text; `feComposite operator="arithmetic"` implements arbitrary per-channel math (`r = k1*i1*i2 + k2*i1 + k3*i2 + k4`), which is enough for contrast boosting, masking, and AND/OR operations; `feTile` crops and replicates pixel probes; `feMorphology` grows/shrinks strokes; `feColorMatrix` moves luma into alpha to build precise masks.
124+
125+
#### Distorting secrets into CAPTCHA-style prompts
126+
127+
If a framable endpoint renders secrets (tokens, reset codes, API keys), the attacker can distort them so they resemble a CAPTCHA and coerce manual transcription:
128+
129+
```html
130+
<svg width="0" height="0">
131+
<filter id="captchaFilter">
132+
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
133+
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
134+
</filter>
135+
</svg>
136+
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
137+
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>
138+
```
139+
140+
The distorted pixels fool the user into “solving” the captcha inside the attacker-controlled `<input>` whose `pattern` enforces the real victim secret.
141+
142+
#### Recontextualizing victim inputs
143+
144+
Filters can surgically delete placeholder/validation text while keeping user keystrokes. One workflow:
145+
146+
1. `feComposite operator="arithmetic" k2≈4` amplifies brightness so grey helper text saturates to white.
147+
2. `feTile` limits the working area to the input rectangle.
148+
3. `feMorphology operator="erode"` thickens the dark glyphs typed by the victim and stores them via `result="thick"`.
149+
4. `feFlood` creates a white plate, `feBlend mode="difference"` with `thick`, and a second `feComposite k2≈100` turns it into a stark luma matte.
150+
5. `feColorMatrix` moves that luma into alpha, and `feComposite in="SourceGraphic" operator="in"` keeps only user-entered glyphs.
151+
6. Another `feBlend in2="white"` plus a thin crop gives a clean textbox, after which the attacker overlays their own HTML labels (e.g., “Enter your email”) while the hidden iframe still enforces the victim origin’s password policy.
152+
153+
Safari struggles with `feTile`; the same effect can be reproduced with spatial mattes built from `feFlood` + `feColorMatrix` + `feComposite` for WebKit-only payloads.
154+
155+
#### Pixel probes, logic and state machines
156+
157+
By cropping a 2–4 px region with `feTile` and tiling it to `100%` of the viewport, the attacker transforms the sampled color into a full-frame texture that can be thresholded into a boolean mask:
158+
159+
```html
160+
<filter id="pixelProbe">
161+
<feTile x="313" y="141" width="4" height="4" />
162+
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
163+
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
164+
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0" result="mask" />
165+
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
166+
<feComposite operator="in" in2="mask" />
167+
<feBlend in2="SourceGraphic" />
168+
</filter>
169+
```
170+
171+
For arbitrary colors, a `feFlood` reference (e.g., `#0B57D0`) plus `feBlend mode="difference"` and another arithmetic composite (`k2≈100`, `k4` as tolerance) outputs white only when the sampled pixel matches the target shade. Feeding these masks into `feComposite` with tuned `k1..k4` yields logic gates: `AND` via `k1=1`, `OR` via `k2=k3=1`, `XOR` via `feBlend mode="difference"`, `NOT` via blending against white. Chaining gates makes a full adder inside the filter graph, proving the pipeline is functionally complete.
172+
173+
Attackers can therefore read UI state without JavaScript. Example booleans from a modal workflow:
174+
175+
- **D** (dialog visible): probe a darkened corner and test against white.
176+
- **L** (dialog loaded): probe the coordinates where the button appears once ready.
177+
- **C** (checkbox checked): compare the checkbox pixel against the active blue `#0B57D0`.
178+
- **R** (red success/failure banner): use `feMorphology` and red thresholds inside the banner rectangle.
179+
180+
Each detected state gates a different overlay bitmap embedded via `feImage xlink:href="data:..."`. Masking those bitmaps with `D`, `L`, `C`, `R` keeps the overlays synchronized with the real dialog and walks the victim through multi-step workflows (password resets, approvals, destructive confirmations) without ever exposing the DOM.
181+
115182
### Browser extensions: DOM-based autofill clickjacking
116183

117184
Aside from iframing victim pages, attackers can target browser extension UI elements that are injected into the page. Password managers render autofill dropdowns near focused inputs; by focusing an attacker-controlled field and hiding/occluding the extension’s dropdown (opacity/overlay/top-layer tricks), a coerced user click can select a stored item and fill sensitive data into attacker-controlled inputs. This variant requires no iframe exposure and works entirely via DOM/CSS manipulation.
118185

119-
- For concrete techniques and PoCs see:
120-
-
186+
- For concrete techniques and PoCs see:
121187
{{#ref}}
122-
browser-extension-pentesting-methodology/browext-clickjacking.md
123-
{{#endref}}
188+
browser-extension-pentesting-methodology/browext-clickjacking.md
189+
{{#endref}}
124190

125191
## Strategies to Mitigate Clickjacking
126192

@@ -223,5 +289,6 @@ if (top !== self) {
223289
- [**https://portswigger.net/web-security/clickjacking**](https://portswigger.net/web-security/clickjacking)
224290
- [**https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html**](https://cheatsheetseries.owasp.org/cheatsheets/Clickjacking_Defense_Cheat_Sheet.html)
225291
- [DOM-based Extension Clickjacking (marektoth.com)](https://marektoth.com/blog/dom-based-extension-clickjacking/)
292+
- [SVG Filters - Clickjacking 2.0](https://lyra.horse/blog/2025/12/svg-clickjacking/)
226293

227294
{{#include ../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)