{"id":"hunt-clickjacking","name":"hunt-clickjacking","summary":"Hunt Clickjacking — X-Frame-Options / CSP frame-ancestorsが欠けているため、攻撃者はターゲットページを見えないiframeに埋め込み、被害者に見えないボタンをクリックさせ(UIの再整理)を騙すことができます。","body":"## What is Clickjacking\n\nClickjacking (UI Redressing) lets an attacker load a target page inside a transparent iframe on a malicious site. The victim sees the attacker's decoy UI but clicks the hidden target UI beneath it. No JavaScript on the target is required.\n\n**Highest-value targets:**\n- Login / authentication pages — force login with attacker credentials\n- Money transfer / checkout / \"confirm payment\" buttons\n- Account settings (email change, password change, 2FA disable)\n- OAuth / social-login \"Authorize app\" confirmation dialogs\n- Admin actions (delete, promote user, change role)\n\n## Protection Headers\n\nTwo mechanisms prevent framing:\n\n```\nX-Frame-Options: DENY              # strongest — blocks all framing\nX-Frame-Options: SAMEORIGIN        # allows same-origin frames only\nContent-Security-Policy: frame-ancestors 'none'     # CSP equivalent of DENY\nContent-Security-Policy: frame-ancestors 'self'     # CSP equivalent of SAMEORIGIN\n```\n\nIf NEITHER is present, the page is frameable from any origin.\n\n## How to Test\n\nHeader-absence is the **trigger for investigation, not the finding**. Two steps:\n\n**Step 1 — Header check (screening).** Fetch the target page and inspect the response headers:\n\n```\ncurl -sI https://target.example/account/transfer | grep -iE 'x-frame-options|content-security-policy'\n```\nIf BOTH `X-Frame-Options` and CSP `frame-ancestors` are absent, the page is a *candidate*. If either is present and restrictive (`DENY`/`SAMEORIGIN`/`frame-ancestors 'none'|'self'`), stop — it's protected.\n\n**Step 2 — Prove it actually frames and clicks (required for a real finding).** Build a minimal PoC and load it in a real browser:\n\n```html\n<!doctype html>\n<h1>Win a prize — click below</h1>\n<iframe src=\"https://target.example/account/transfer\"\n        style=\"opacity:0.1;position:absolute;top:0;left:0;width:1000px;height:800px\"></iframe>\n```\nConfirm ALL of the following, or it is not exploitable:\n- The page **actually renders inside the iframe** (no framebusting JS that blanks/redirects it — e.g. `if(top!==self)` breakout, or a `Sec-Fetch-Dest`/JS frame check).\n- The **sensitive action still works while framed** — critically, the action must succeed *cross-site*. If it relies on a session cookie set `SameSite=Lax` or `SameSite=Strict` (the modern default), the cookie is **not** sent on the cross-site framed request, and the clickjack fails. Verify the victim's authenticated state carries into the frame.\n- The target is a **state-changing action** (transfer, settings/email/password change, 2FA disable, OAuth authorize, admin action), not a read-only page.\n\n**Strategy:** target the most sensitive action pages first — severity scales directly with what the victim is tricked into doing.\n\n## False Positives\n\n- Public, read-only pages (home/marketing) lacking frame protection are low/informational — no sensitive action to redress.\n- APIs and non-HTML endpoints (JSON, images) are not clickjacking targets.\n- **Header-absence alone is NOT a finding.** SameSite cookies, framebusting JS, or the lack of any sensitive framed action can each fully defeat it — which is why Step 2 is mandatory.\n\n## Proof Requirements\n\nA valid clickjacking report shows: (1) the target page rendered inside an attacker-controlled iframe in a real browser, (2) a sensitive state-changing action reachable by a framed click while the victim is authenticated (cookies survive the cross-site context), and (3) a screenshot/recording of the overlay. Reporting missing headers with no working frame PoC is a documentation-quality issue, not a vulnerability.","author":"@elementalsouls","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/elementalsouls/Claude-BugHunter/tree/main/skills/hunt-clickjacking","license":"MIT","category":"review","lang":"en","tokens":848,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["target.example"]}}