XSSのその先へ:Permissions Policyによる「攻撃の多層防御」とブラウザの制圧
XSS(クロスサイトスクリプティング)を「単なるスクリプトの注入」と捉えているなら、それは時代錯誤だ。我々が対峙しているのは、もはやJavaScriptの実行権限を奪うだけの単純なボットではない。巧妙な攻撃者は、XSSを足がかりにブラウザの強力なAPI——カメラ、マイク、ジオロケーション、あるいはWeb BluetoothやWeb USB——を悪用し、エンドポイントそのものを物理的な盗聴デバイスや踏み台へと変貌させる。
本稿では、XSSを完全に封じ込めることが難しいレガシーなアーキテクチャにおいて、Permissions Policy(旧 Feature-Policy)をいかに「防波堤」として機能させ、攻撃者の足元をすくい取るかを解説する。
—
1. 攻撃の構図:XSSは「入り口」に過ぎない
多くのエンジニアはContent Security Policy (CSP) でXSSを防ごうと躍起になる。確かにCSPは重要だ。しかし、複雑化したモダンなWebアプリケーションにおいて、インラインスクリプトやサードパーティライブラリの脆弱性を100%排除するのは、現実的には「終わりのないパッチ当て」に等しい。
攻撃者がXSSに成功した瞬間、何が起きるか。彼らは navigator.mediaDevices.getUserMedia を呼び出し、ユーザーのPCの内蔵カメラを起動しようとする。あるいは、位置情報を取得して物理的な追跡を試みるかもしれない。
ここで「Permissions Policy」がなければ、ブラウザはそのリクエストを正当なものとして受け入れてしまう。Permissions Policyは、アプリケーションの機能権限をコードベースではなく、ブラウザのランタイム側でハードコードされた制約として押し付けるための防衛線だ。
—
2. Permissions Policyによるゼロトラスト・ブラウザ設計
Permissions Policyは、HTTPレスポンスヘッダーを通じて、ブラウザの特定APIに対する「使用許可」を宣言する。これは、万が一XSSで攻撃者がJavaScriptの実行権を奪ったとしても、攻撃者が「やりたいこと」を物理的に実行させないための強力なガードレイルとなる。
実装例:防御的ヘッダーの構成
以下は、攻撃者が悪用しやすい機能を徹底的に制限した設定例だ。
セキュリティ要件:不要な強力APIは全て無効化し、必要なものだけを明示的に許可する
Permissions-Policy:
camera=(),
microphone=(),
geolocation=(),
payment=(),
usb=(),
interest-cohort=(),
autoplay=(self)
camera=()/microphone=(): 空の括弧は「どのオリジンからもアクセスさせない」ことを意味する。XSSでスクリプトが注入されても、これらのAPIを呼び出した瞬間にブラウザは例外をスローする。geolocation=(): 位置情報は特にプライバシーリスクが高い。ビジネス上不要なら即座に遮断すべきだ。interest-cohort=(): GoogleのFLoC(現在は代替技術へ移行中だが)のようなトラッキング系APIを無効化し、プライバシーの漏洩を防ぐ。
—
3. 監査と運用の極意:なぜ「設定」で終わらせてはいけないのか
最高峰のアーキテクトであれば、設定を書いて終わりという甘い判断はしない。この防御層を維持するための運用フローこそが重要だ。
監査の観点:
1. API利用の棚卸し: 開発チームに対し、「なぜその機能が必要か」を論理的に説明させる。不要なAPIがホワイトリストに入っている状態は、そのまま攻撃者の武器庫になる。
2. レポート機能の活用: report-to ディレクティブを併用し、ポリシー違反を監視せよ。意図しないAPIコールが発生している場合、それはXSS攻撃の予兆、あるいは検知漏れしていた悪意あるサードパーティスクリプトの挙動そのものだ。
限界を理解する:
Permissions Policyは「機能の制限」であって、XSSそのものを消し去る魔法ではない。データ漏洩(Cookieの窃取やトークンの抜き取り)は依然として可能だ。だからこそ、CSP(Content Security Policy)との多層防御が必須となる。
- CSP: スクリプトの実行元を制限する(「何を」実行させるか)
- Permissions Policy: APIの実行権限を制限する(「何に」アクセスさせるか)
この2つが組み合わさって初めて、ブラウザという「脆弱な実行環境」を、堅牢なサンドボックスとして定義できる。
—
4. 結び:エンジニアの責務
昨今の生成AIの普及により、プロンプトインジェクションを通じた攻撃パターンの複雑化も進んでいる。しかし、根本的な防御の思想は変わらない。「信頼する範囲を極小化し、機能の権限を最小特権の原則に基づいて絞り込む」こと。
「ブラウザの機能が制限されて動かない」と文句を言う開発者がいたら、それはあなたが正しいセキュリティ設計をしている証拠だ。技術とは、自由度を奪うことではなく、攻撃可能な表面積(Attack Surface)を削り取り、安全な領域を定義することに他ならない。
次にデプロイする際、ぜひこのヘッダーを加えてみてほしい。サーバーログに潜む、攻撃者の「失敗したリクエスト」の山こそが、あなたのアーキテクチャが機能している最高の勲章になるはずだ。
コメント