Content Security PolicyとCMP:CSPと同意を両立させる

足並みをそろえるべき2つのセキュリティ層

Content Security Policy(CSP)は、ページがスクリプト、スタイル、画像、フレーム、ネットワークリクエストをどのソースから読み込んでよいかをブラウザに伝えます。同意管理プラットフォームはその逆の役割を果たし、ユーザーの選択に基づいて、それらのスクリプトのうちどれを実行してよいかを決定します。両者を別々に設定すると、衝突します。CSPにブロックされてCMPが読み込めなくなるか、CMPや広告タグに対応するためにCSPを緩めすぎて、もう何も保護しなくなってしまうのです。

このガイドでは、CMPが通常必要とするCSPディレクティブ、nonceがスクリプトのインジェクションとどう関わるか、そしてバナーを壊さずに変更を導入する方法を説明します。

CMPがCSPに通常求めるもの

正確な要件はベンダーによって異なるため、必ずCMP自身のドキュメントから始めてください。一般的には、次のディレクティブを確認します。

TCFのサイトでは、CMPがページ上に__tcfapiLocatorという名前のロケータフレームも作成することを覚えておいてください。このフレームはリモートのソースなしで作成されるため、通常はframe-srcのエントリは不要ですが、テストで確認する価値があります。

インラインスタブの問題

ほとんどのCMPは、メインのCMPが読み込まれる前に他のスクリプトが呼び出しをキューに入れられるよう、小さなインラインスクリプト(スタブ)をページのheadに置くよう求めます。厳格なCSPは、明示的に許可しない限りインラインスクリプトをブロックします。選択肢は3つあります。

  1. nonce。レスポンスごとにランダムな値を生成し、CSPヘッダーに'nonce-...'として、またスタブの<script>タグに追加します。動的なページに最も柔軟な選択肢です。
  2. ハッシュ。スタブの内容そのもののSHA-256ハッシュをscript-srcに追加します。静的サイトでうまく機能しますが、スタブを少しでも、空白ひとつでも変更すると機能しなくなります。
  3. スタブのセルフホスティング。自分のドメイン上の外部ファイルとして配置し、'self'でカバーします。十分早く読み込まれるよう注意が必要です。

近道として'unsafe-inline'を使うのは避けてください。すべてのインラインスクリプトを許可してしまい、CSPが提供する保護の多くが失われます。

nonceとCMPがインジェクションするスクリプト

同意があるまでスクリプトをブロックするCMPは、多くの場合、スクリプトを保留し、後からインジェクションすることで動作します。nonceベースのCSPでは、それらのインジェクションされたスクリプトも許可される必要があります。一般的なアプローチは2つあります。

タグマネージャーでも同じ問題が生じます。広告やアナリティクスのタグをタグマネージャー経由で読み込む場合は、nonceに関するそのドキュメントに従い、CMPとタグマネージャーが一貫したアプローチを使うようにしてください。

広告タグがCSPを難しくする

プログラマティック広告は多数のドメインからスクリプトとフレームを読み込み、そのリストは需要パートナーの変化に伴って変わります。パブリッシャーは通常、次のどちらかを選びます。

どちらの場合でも、CMPはワイルドカードだけでカバーされるのではなく、明示的な許可リストに入れておくべきです。そうすれば、CSPの変更がバナーを気づかないうちに無効にすることはありません。

Report-Onlyモードで導入する

まずContent-Security-Policy-Report-Onlyヘッダーを使います。ブラウザは何もブロックせずに違反を報告するため、新しいポリシーが何を壊すかを確認できます。

  1. レポートエンドポイントを指定して、ポリシーをreport-onlyモードでデプロイします。
  2. クリーンなブラウザプロファイルでページを読み込み、初回訪問、すべて承諾、すべて拒否、カスタム選択、撤回という同意フローの全体を通して確認します。
  3. 違反レポートとブラウザコンソールで、ブロックされたCMPリソースがないか確認します。
  4. ポリシーを調整し、その後で強制モードに切り替えます。
  5. 強制後もレポートを有効にしておき、退行を検知します。

CSPの競合の症状

重要なポイント

← ブログ すべて読む →