Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 71 additions & 4 deletions src/pentesting-web/clickjacking.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,81 @@ A code example can be found in [this page](https://www.paulosyibelo.com/2024/12/
> [!WARNING]
> 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**.

### SVG Filters / Cross-Origin Iframe UI Redressing

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:

```html
<iframe src="https://victim.example" style="filter:url(#displacementFilter4)"></iframe>
```

* 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.

#### Distorting secrets into CAPTCHA-style prompts

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:

```html
<svg width="0" height="0">
<filter id="captchaFilter">
<feTurbulence type="turbulence" baseFrequency="0.03" numOctaves="4" result="noise" />
<feDisplacementMap in="SourceGraphic" in2="noise" scale="6" xChannelSelector="R" yChannelSelector="G" />
</filter>
</svg>
<iframe src="https://victim" style="filter:url(#captchaFilter)"></iframe>
<input pattern="^6c79 ?7261 ?706f ?6e79$" required>
```

The distorted pixels fool the user into “solving” the captcha inside the attacker-controlled `<input>` whose `pattern` enforces the real victim secret.

#### Recontextualizing victim inputs

Filters can surgically delete placeholder/validation text while keeping user keystrokes. One workflow:

1. `feComposite operator="arithmetic" k2≈4` amplifies brightness so grey helper text saturates to white.
2. `feTile` limits the working area to the input rectangle.
3. `feMorphology operator="erode"` thickens the dark glyphs typed by the victim and stores them via `result="thick"`.
4. `feFlood` creates a white plate, `feBlend mode="difference"` with `thick`, and a second `feComposite k2≈100` turns it into a stark luma matte.
5. `feColorMatrix` moves that luma into alpha, and `feComposite in="SourceGraphic" operator="in"` keeps only user-entered glyphs.
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.

Safari struggles with `feTile`; the same effect can be reproduced with spatial mattes built from `feFlood` + `feColorMatrix` + `feComposite` for WebKit-only payloads.

#### Pixel probes, logic and state machines

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:

```html
<filter id="pixelProbe">
<feTile x="313" y="141" width="4" height="4" />
<feTile x="0" y="0" width="100%" height="100%" result="probe" />
<feComposite in="probe" operator="arithmetic" k2="120" k4="-1" />
<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" />
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
<feComposite operator="in" in2="mask" />
<feBlend in2="SourceGraphic" />
</filter>
```

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.

Attackers can therefore read UI state without JavaScript. Example booleans from a modal workflow:

- **D** (dialog visible): probe a darkened corner and test against white.
- **L** (dialog loaded): probe the coordinates where the button appears once ready.
- **C** (checkbox checked): compare the checkbox pixel against the active blue `#0B57D0`.
- **R** (red success/failure banner): use `feMorphology` and red thresholds inside the banner rectangle.

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.

### Browser extensions: DOM-based autofill clickjacking

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.

- For concrete techniques and PoCs see:
-
- For concrete techniques and PoCs see:
{{#ref}}
browser-extension-pentesting-methodology/browext-clickjacking.md
{{#endref}}
browser-extension-pentesting-methodology/browext-clickjacking.md
{{#endref}}

## Strategies to Mitigate Clickjacking

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

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