サマリ
CookieやlocalStorage等でセッション管理しているウェブサイトがクリックジャッキング対策していない場合、どの条件で被害を受けるかを説明する。SameSite属性のないCookieでセッション管理しているウェブサイトは、主要ブラウザのデフォルト設定ではクリックジャッキングの影響を受けない。一方、loaclStorageにトークン類を格納するウェブサイトでは、Google Chrome等のブラウザでクリックジャッキングの影響がある。また、ブラウザの設定を変更した場合の影響についても説明する。
クリックジャッキングとは
クリックジャッキングとは、一言で説明すると「ウェブサイト利用者に意図しないクリック(タップ)をさせる」攻撃です。ウェブサイト上で意図しないクリックを勝手にさせられると、重大な結果になる場合があります。例えば、このURLを閲覧すると、以下のようにTwitterにて「犯行予告を投稿する」画面になり、「ツイートする」を押すと、押した人のアカウントで犯行予告をツイートする結果になります。Twitterのこの機能はウェブインテントと呼ばれます。
このような拙い「攻撃」だと、被害者は画面内容を見た結果ツイートボタンは押さないわけですが、これにiframeを用いた仕掛けを組み合わせて「知らない間にボタンを押させる攻撃」がクリックジャッキングです。具体的には、iframeを用いて、下図のようにボタンを押させるための罠と、Twitter等の掲示板の画面を重ねます。
この際、掲示板を手前に配置してCSS設定により透明にします。一方罠サイトは奥側に配置します。すると、見た目上は罠サイトだけが見えますが、ボタンをクリックすると手前側の掲示板のボタンを押したことになり、ログイン中の利用者のアカウントで意図しない投稿がされます。これがクリックジャッキングです。現実のTwitterはクリックジャッキング対策がされているので、この攻撃は成立しません。
この例では「意図しない投稿」でしたが、これ以外に、設定変更や退会など「クリックだけでできる操作」全てで影響がありえます。
クリックジャッキング対策には、以下のようなレスポンスヘッダを出力することで行われます。
Content-Security-Policy: frame-ancestors 'none';
上図はCSPを用いた対策ですが、伝統的なX-Frame-Optionsヘッダを用いた対策も有効です。
しかしながら、上記対策をしていない場合でも、モダンブラウザでは、iframe内のコンテンツからCookieおよびlocalStorageへのアクセスが制御されていて、クリックジャッキング攻撃ができないケースが多くなっています。
本稿では、モダンなブラウザの利用者がクリックジャッキング被害を受ける条件について説明します。
検証方法
今回は、クリックジャッキングの影響の有無を、iframe内のウェブページがCookieやlocalStorageの値を受け取れるかどうかで判断することにしました。もしもiframe内のページがCookieやlocalStorageにアクセスできない場合、ページはログイン状態にはならず、被害者のアカウントでの投稿や設定変更などはできないからです。
下図は検証環境の模式図です。サイトAがクリックジャッキング脆弱なサイト、サイトBは罠サイトです。
サイトAのログインを模して、CookieやlocalStorage、sessionStorageをセットします(図の左側)。この後サイトBに遷移しますが、サイトB内にiframeがあり、その中にサイトAのページがあります(図の右側)。このiframe内のサイトAのページでCookie、localStorage、sessionStorageの値を表示して、これらの値を受け取れているかを確認します。
CookieのSameSite属性は以下の3種類のものを用意しました。SameSite属性の意味についてはこちらの記事を参照ください。
- SameSite属性なし
- SameSite=None
- SameSite=Lax
SameSite属性なしは伝統的なセッション管理を想定しています。SameSite=Laxの場合、iframe内のコンテンツにCookieは送信されないはずですが、比較のためテスト条件に加えました。
検証結果
検証結果を下表に示します。
結果の要約は下記の通りです。
- SameSite属性のないCookieでセッション管理しているサイトは全てのブラウザにてクリックジャッキングの被害を受けない
- localStorageでセッション管理しているサイトは、Google Chrome、Edge、Opera(デスクトップ、Android)のユーザが被害を受ける
- Brave、Firefox、Safariの利用者はいずれのケースでもクリックジャッキングの被害を受けない
このように、ブラウザのセキュリティ機能の差により、クリックジャッキング被害の条件が変わっています。
各ブラウザのセキュリティ機能
次に、各ブラウザのセキュリティ機能がどのようにクリックジャッキングを防いでいるかを説明します。
Chromium系ブラウザの防御はデフォルトSameSite=Lax
CookieのSameSite属性にてLaxあるいはStrictを指定した場合、iframe内に置かれたページに対してはCookieは送信されません。これはすべてのブラウザに共通の仕様ですが、Chromium系のブラウザ(Google Chrome、Edge、Brave、Opera…)では、SameSite属性のないCookieはSameSite=Laxとして扱われます(参考)。
このため、SameSite=Noneを明示的に設定していないCookieは、iframe内のページには送信されないことになります。SameSite属性は、もともとはCSRF対策を意図した機能と思われますが、クリックジャッキング対策にも効果があります。
デフォルトSameSite=Laxの効果はCookieのみであるため、sessionStorageとlocalStorageには効果が及びません。
※注
SameSite属性のないCookieは、Cookieが生成されてから2分以内であれば、クロスサイトのPOSTリクエストに付与されます(参考)が、iframeの場合はこの2分間の猶予期間はなく、ただちにSameSite=Laxとして扱われます。
Firefoxの防御機能は包括的クッキー保護(Total Cookie Protection)
Firefoxは2022年1月11日にデフォルトSameSite=Laxを導入しましたが、非互換を理由に直後にキャンセルされました(参考)。現在でも、SameSiteのデフォルトは、SameSite=None相当です。
一方、Firefoxは2022年6月14日に包括的 Cookie 保護(Total Cookie Protection:TCP)と呼ばれる機能を投入しました。TCPはセキュリティ目的というよりはプライバシー保護を目的としたものですが、クリックジャッキング防御にも効果があります。
下図は包括的Cookie保護(TCP)のイメージ図です(引用元)。
従来は一つのCookieの入れ物(cookie jar)をすべてのサイトで共有していました(上図左)が、TCPが有効になるとサイト毎にcookie jarが独立するようになります(上図右)。これだけだと抽象的でわかりにくいので、サイトAがサイトB、サイトCのiframeにて表示されている様子を用いて説明します(下図)。
上図のように、サイトAのCookieは、単独で表示されている場合(左)、サイトBのiframe内で表示されている場合(中央)、サイトCのiframeで表示されている場合(右)で、それぞれ別の値となります。この機能はサードパーティCookieによるトラッキングを防ぐ目的で導入されたものですが、セッション管理のCookieもiframe内では分離・保護されるため、結果としてクリックジャッキングに対する防御として作用します。また、Cookieだけでなく、sessionStorageやlocalStorageもサイト毎に分離されます。
なお、実験による検証の結果、Braveブラウザにも包括的Cookie保護と同様の機能が実装されているようです(sessionStorageの挙動はFirefoxともSafariとも異なりますが、詳細は省略します)。BraveはChromiumベースのブラウザなので、デフォルトSameSite=Laxも実装されています。
Safariの防御機能はITP(Intelligent Tracking Prevention)
Safari(WebKit)にはITP(Intelligent Tracking Prevention)というトラッキング防止機能があります。これにより、結果としてクリックジャッキングも防御されています。
下図は、ITPによりiframe内のページのCookieがどうなるかを模式的に示しています。
サイトAでセットされたCookieは、サイトBにiframeで埋め込まれてもCookieは送信されず、またレスポンスのSet-Cookieも無視されます。すなわち、iframe内ではCookieの送信も受信もされないということになります。
一方、sessionStorageとlocalStorageについては、FirefoxのTCPのような挙動になります。すなわち、サイト毎に分離された形になります。この挙動はWebKitのドキュメントに記載されています。
Partitioned Third-Party Storage
Third-party LocalStorage and IndexedDB are partitioned per first-party website and also made ephemeral.
試訳: サードパーティのlocalStorageとindexedDBはファーストパーティのウェブサイト毎に分離され、またエフェメラル(一時的)なものになります。
すなわち、localStorage等については、iframe等に埋め込まれていた場合、ファーストパーティのウェブサイト毎に別の名前空間になります。
しかし、実験の結果はsessionStorageも上記の分離がなされていました。Safari 16.0まではsessionStorageは分離されておらず、Safari 16.1以降においてsessionStorageもlocalStorage同様のサイト毎の分離がされているようです。私はこの件についてのドキュメントを発見できていませんので、ドキュメントをご存知の方はぜひ教えてください。また、エフェメラルいうのは、ブラウザを終了すると削除されるという意味です。通常localStorageはブラウザを終了しても保持されますが、iframe等のサードパーティで保存されたlocalStorageはブラウザの終了と共に削除されます。一方、FirefoxのlocalStorageはサイト毎に分離されていますが、ブラウザを終了しても、localStorageの値は保持されます。
防御機能を無効化するとどうなるか
ここまで、ブラウザの提供する保護機能により、クリックジャッキング攻撃から防御される仕組みをご紹介しました。しかし、これらの機能は利用者が無効にすることができます。以下、利用者が保護機能を無効にした場合の影響を調べるため、まずはブラウザ毎にセキュリティ機能を無効化する方法を説明します。以下は、セキュリティを低下させる設定なので、検証以外では使用しないことをお勧めします。また試用した後は忘れずに戻しておいてください。
Google Chrome、Edgeの場合
Google Chrome等のChromium系ブラウザにて、デフォルトSameSite=Laxを無効化するには、Windowsの場合レジストリのLegacySameSiteCookieBehaviorEnabledForDomainListにて、無効化するドメインのリストを指定します。参考記事によると、この設定は暫定的なもので将来変更される見込みです。設定例を下図に示します。この設定では、すべてのドメインにてデフォルトSameSite=Laxを無効化しています。危険な設定なので、検証用途以外には使わないでください。
同じ方法でEdgeでも設定可能です。
Firefoxの場合
FirefoxのTCPを無効化するためには、設定|プライバシーとセキュリティから、強化型トラッキング防止機能から、カスタムを選択して、Cookieのチェックを外すか、その右のセレクトボックスで「クロスサイトトラッキングCookie(一番上)」を選択します。
Safari
SafariのITPを無効化するには、Safariの設定からプライバシーを選び、「サイト超えトラッキングを防ぐ」のチェックを外します。
結果
上記の設定変更をした結果を下表に示します。赤字で(*)付きで示した項は設定変更により条件が変わっていることを示します。
考察
前述の設定変更により、以下の状態となりました。
- ブラウザ側の変更により、ほぼ全ての条件でクリックジャッキングの影響を受けるようになる
- FirefoxのTCP、およびSafariのITPはプライバシー強化のための機能だが、セキュリティの効果もある
- SameSite=Lax設定はクリックジャッキング対策としても効果が高い
各ブラウザの設定変更の中で、もっとも現実にありそうなものがSafariのITPの無効化です。「サイト超えトラッキングを防ぐ」でGoogle検索するとトップに表示されるのが、以下のYahoo! JAPANの記事です。
iOS 11以降では、「サイト越えトラッキングを防ぐ」がオン(有効)になっている場合があります。
「サイト越えトラッキングを防ぐ」がオンになっている場合、Cookie(クッキー)がSafari上に残らなくなります。
Yahoo! JAPANでは、複数のサービスでCookieを使用しているため、「サイト越えトラッキングを防ぐ」をオンにしていると、サービス内の機能が限定されるなど、一部のサービスを利用できません。
以下の手順を参考に、「サイト越えトラッキングを防ぐ」機能をオフにしてからYahoo! JAPANのサービスをご利用ください。
iPhone向けSafariで「サイト越えトラッキングを防ぐ」機能をオフにするより引用
しかし、当該の設定変更を行うと、Yahoo!以外のサイトでもセキュリティを弱くする結果になります。このページには以下のような記載もありますが、
注意
「サイト越えトラッキングを防ぐ」機能の設定変更は、お客様ご自身の責任において変更してください。
「お客様ご自身の責任において変更」と書いてありますが、変更による影響は何も説明されていないため、この書き方はいかがなものかという感想を持ちました。
まとめ
- SameSite属性のないCookieによるセッション管理という伝統的なサイトはモダンなブラウザのデフォルト設定ではクリックジャッキング攻撃の影響はない
- localStorageにトークン類を保存する実装の場合、Chromium系のブラウザ(Chrome、Edge、Opera)ではクリックジャッキング攻撃の影響がある
- ブラウザのトラッキング機能を解除するとクリックジャッキング攻撃の影響を受けやすくなる
- アプリケーション提供者は、ブラウザの設定によらずクリックジャッキングを防御するために、CSPやX-Frame-Optionsによりクリックジャッキング対策を実施すること
- サイト運営者は、ブラウザの設定変更を促さないこと
- サイト利用者は、ブラウザの設定を安易に変更しないこと