ssecutils
Security

クリックジャッキング詳解 - 透明iframeとX-Frame-Options/CSPで防ぐ

著者 aki公開 更新 9

クリックジャッキングとは

クリックジャッキング(Clickjacking)は、攻撃者のページに被害サイトを透明な iframe で重ね、被害者が「攻撃者のページのボタンを押した」と思っている裏で、本物のサイトのボタンをクリックさせる攻撃です。UIリドレッシング(UI Redressing)と呼ばれる攻撃ファミリーの代表例で、視覚と実際の操作のズレを突くのが本質です。

被害者はログイン中の状態でこの罠に引っかかると、自分の意思で「OK」を押したつもりが、実は SNS の「フォロー」、銀行の「振込承認」、設定画面の「公開範囲を全公開に変更」といった重大操作を踏んでしまいます。

典型的な攻撃シナリオ

攻撃者は evil.example に次のような HTML を仕込みます:

<style>
  iframe {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    opacity: 0.001;       /* 視覚的にはほぼ透明 */
    z-index: 999;
  }
  .lure {
    position: absolute;
    top: 280px; left: 420px;
    font-size: 32px;
  }
</style>

<button class="lure">🎁 無料ガチャを引く</button>
<iframe src="https://bank.example/transfer?to=attacker&amount=1000000"></iframe>

ボタンと iframe 内の「送金実行」ボタンが画面上で同じ位置に重なるよう座標を調整しておきます。被害者は「無料ガチャ」だと思って透明 iframe をクリックすると、実際には bank.example送金実行ボタンを押していることになります。

被害者は bank.example にログイン中(Cookie 保持)なので、サーバー側からは正規ユーザーの操作にしか見えません。CSRF と似ていますが、CSRF が「リクエストを自動発火」させるのに対し、クリックジャッキングは 「被害者本人にクリックさせる」のが違いです。これにより、CAPTCHA や「本当に実行しますか?」確認ダイアログさえも被害者本人が突破してしまいます。

UIリドレッシング攻撃の亜種

名称仕組み典型的な被害
クリックジャッキング透明iframe を重ねてクリックを奪う振込、購入、設定変更
LikejackingSNS の「いいね」ボタンを透明化して重ねる意図しないシェア、フォロー
CursorjackingCSS でカーソル画像を実際の位置からずらす表示と実クリック位置の不一致
Drag & Drop Jackingドラッグ操作で別ウィンドウへデータ流出フォーム値・トークン盗難
Double-clickjackingダブルクリックの隙にダイアログを差し替えるOAuth 認可の同意奪取(2024年話題)

防御1: CSP frame-ancestors(現代の主役)

Content-Security-Policy ヘッダの frame-ancestors ディレクティブが、現代における正攻法の防御です。サイトを iframe で埋め込めるオリジンを明示的にホワイトリスト化します。

# 自サイトをどこからも iframe 埋め込みさせない(推奨)
Content-Security-Policy: frame-ancestors 'none'

# 同一オリジンのみ許可
Content-Security-Policy: frame-ancestors 'self'

# 特定パートナーサイトを許可
Content-Security-Policy: frame-ancestors 'self' https://partner.example

ブラウザが iframe 描画前にこのヘッダを確認し、許可されていなければ描画自体をブロックします。frame-ancestors は CSP Level 2 から導入され、現代の主要ブラウザでサポートされています。

防御2: X-Frame-Options(古い仕組み・現役)

X-Frame-Options は CSP frame-ancestors より古い仕組みですが、互換性のため今も併用されます。

挙動
DENYどのオリジンからも iframe 埋め込み不可
SAMEORIGIN同一オリジンからのみ iframe 埋め込み可
ALLOW-FROM uri指定 URI から許可(非推奨・サポート不十分)

現代の指針は 「CSP frame-ancestors を主役、X-Frame-Options は古いブラウザ向け保険」です。両方設定しておけば最大互換。両者の値が矛盾した場合、CSP frame-ancestors が優先されます(CSP Level 2 の仕様)。

本サイト secutils.jp でも次の設定で対応しています:

Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY

実体験:Security Headers Analyzer を作って意識したこと

Security Headers Analyzer を作る中で、クリックジャッキング対策について実際に意識しました。クリックジャッキングは、単純に「悪意のあるサイトにリンクを貼られる」というイメージではなく、正規のサイトを別のページの中に透明な iframe などで埋め込んで、ユーザーが意図しない操作をしてしまう可能性があるという点が印象に残りました。

そこで、secutils 自体についても、自分のサイトが他のサイトから iframe として埋め込まれてしまって問題ないのかを考えるようになりました。X-Frame-Options や CSP の frame-ancestors によって、どのサイトから自分のページをフレーム内に表示できるのかを制御できることを知って、セキュリティヘッダーは単に「設定しておけばいいもの」ではなく、それぞれに具体的な攻撃シナリオがあるんだと実感しました。Security Headers Analyzer を作ったことで、こうしたヘッダーを実際のサイトに設定する側の視点も持てるようになりました。

防御3: フレームバスティング(非推奨)

2010年代以前は、JavaScript で自身が iframe 内かを判定して脱出する フレームバスティング(frame busting)コードがよく使われました:

if (top !== self) {
  top.location = self.location;
}

しかしこの手法は、HTML5 の sandbox 属性で iframe を起動すれば top.location への書き込みを禁止できるため、容易にバイパスされます。現代では frame-ancestors を使うべきで、フレームバスティングだけに頼るのは危険です。

防御4: SameSite Cookie の補完効果

Cookie に SameSite=Lax または Strict を設定すると、クロスサイトの iframe からは Cookie が送られなくなり、結果としてクリックジャッキングの被害を緩和できます。ただし「Cookie が無くてもクリックで実行できる操作」(公開フォーム、認証不要API 等)には効きません。主防御は CSP frame-ancestors、SameSite は補完と考えます。

実装チェックリスト

  • すべてのページに Content-Security-Policy: frame-ancestors 'none' または 'self' を返している
  • 古いブラウザ対策として X-Frame-Options: DENY または SAMEORIGIN も併用している
  • iframe 埋め込みを許可する必要がある場合、許可先オリジンを明示している(* ワイルドカードは使わない)
  • ログイン・支払い・設定変更などの重大操作には、明示的な再認証や CAPTCHA を併用している
  • Cookie に SameSite 属性を設定している
  • サイトを securityheaders.com で定期チェックしている

まとめ

クリックジャッキングは「視覚的な錯誤を突いて、被害者本人にクリックさせる」攻撃で、CAPTCHA や確認ダイアログでさえ防げない厄介な側面があります。防御の本命は CSP frame-ancestors。これ1行で iframe 埋め込み自体をブラウザ層で遮断できます。X-Frame-Options も合わせて返し、古いブラウザにも対応するのが現代のベストプラクティスです。

Cookie 設定の確認には Cookie Parser ツールで SameSite 属性を可視化できます。HTTP セキュリティヘッダ全般については HTTP セキュリティヘッダ詳解も合わせてご覧ください。

この記事を書いた人
akiサイバーセキュリティ実務者 / エンジニア

サイバーセキュリティ業界で実務に携わるエンジニア。脆弱性・認証・暗号・ネットワークなど、現場で必要になる知識を開発者・運用担当者向けにかみ砕いて解説しています。

運営者・編集方針について

本記事は一般的な情報提供を目的とした解説であり、特定環境での動作・安全性・成果を保証するものではありません。実際の対策の適用は、各自の環境と責任において判断してください。

Tool companion

この記事と一緒に使えるツール

Related reading

関連記事

Network17
プロキシとリバースプロキシの違い - 「誰の代理か」で理解する置く人も守る対象も逆になる2つのプロキシを、RFCの定義で整理します。CONNECTでHTTPSが中継される仕組み、実際のサイトのヘッダーに残るリバースプロキシの痕跡、手元で検証したX-Forwarded-Forの偽装、502/504の切り分けやリダイレクトループなど実務でハマる点まで扱います。
Security15
CompTIA Security+ 完全ガイド - 難易度・出題範囲・日本語受験SY0-701 の試験形式と5つの出題ドメイン、2024年から始まった日本語受験、支援士・CISSPとの難易度比較、3年ごとの更新の仕組み、平日30分から回せる学習ロードマップを整理します。各ドメインで問われる内容は、本サイトのどの解説記事で補えるかも対応づけました。
Security18
情報セキュリティ10大脅威 2026 - IPAの順位を自社の優先順位に翻訳するIPAの「情報セキュリティ10大脅威 2026」を、順位の丸写しではなく実務の優先順位に落とし込むために読み解きます。前年からの変動、初選出された3位「AIの利用をめぐるサイバーリスク」の中身、各脅威に対応する国内事例、着手順の決め方まで整理します。
Security9
HTTPセキュリティヘッダー詳解CSP、HSTS、X-Frame-Options、Permissions-Policy など、ブラウザ防御に効くヘッダーを整理します。