コンテンツ セキュリティ ポリシー(CSP)は、ページに読み込まれたすべてのコンテンツがサイト所有者によって信頼されていることを確認するのに役立ちます。CSP は、攻撃者によって挿入された安全でないスクリプトをブロックできるため、クロスサイト スクリプティング(XSS)攻撃を軽減できます。ただし、厳格さが十分でなければ、CSP は簡単に回避できます。詳しくは、厳格なコンテンツ セキュリティ ポリシー(CSP)を使用してクロスサイト スクリプティング(XSS)を軽減するをご覧ください。Lighthouse では、メイン ドキュメントに適用されている CSP を収集し、回避できる場合は CSP 評価者から問題を報告します。
バイパス不可能な CSP に必要なプラクティス
CSP が回避されるようにするには、次の方法を実施してください。CSP が回避できる場合、Lighthouse は重大度「高」の警告を発行します。
CSP のターゲットは XSS
XSS をターゲットとするには、CSP に script-src
、object-src
、base-uri
のディレクティブを含める必要があります。また、CSP には構文エラーがない必要があります。
script-src
と object-src
はそれぞれ安全でないスクリプトと安全でないプラグインからページを保護します。または、script-src
や object-src
などの多くのディレクティブの代わりに、default-src
を使用して広範なポリシーを構成することもできます。
base-uri
は、不正な <base>
タグの挿入を防ぎます。このタグを使用すると、すべての相対 URL(スクリプトなど)が攻撃者の管理ドメインにリダイレクトされるおそれがあります。
CSP はノンスまたはハッシュを使用して許可リストのバイパスを回避する
script-src
の許可リストを構成する CSP は、信頼できるドメインからのすべてのレスポンスが安全であり、スクリプトとして実行できるという前提に依存します。しかし、この前提は最新のアプリケーションには当てはまりません。JSONP インターフェースの公開や AngularJS ライブラリのコピーのホスティングといった一般的で無害なパターンにより、攻撃者は CSP の領域から抜け出せる可能性があります。
実際には、アプリケーション作成者には明らかではないかもしれませんが、XSS バグを持つ攻撃者によって script-src
許可リストの大部分が回避され、スクリプト インジェクションに対する保護がほとんど提供されません。一方、ノンスベースのアプローチとハッシュベースのアプローチではこのような問題が生じないため、より安全なポリシーを採用して維持するのが容易です。
たとえば、次のコードは、信頼できるドメインでホストされている JSONP エンドポイントを使用して、攻撃者が制御するスクリプトを挿入します。
CSP:
script-src https://trusted.example.com
HTML:
<script src="https://trusted.example.com/path/jsonp?callback=alert(document.domain)//"></script>
CSP がバイパスを回避するには、ノンスまたはハッシュを使用するスクリプトを個別に許可し、許可リストの代わりに「strict-dynamic」を使用する必要があります。
安全な CSP のためのその他の推奨事項
セキュリティと互換性を強化するために、次の方法を実装します。CSP が推奨事項のいずれも遵守していない場合、Lighthouse は重大度「中」の警告を発行します。
CSP レポートを構成する
レポート先を設定すると、障害をモニタリングするのに役立ちます。report-uri
ディレクティブまたは report-to
ディレクティブを使用して、報告先を設定できます。report-to
は現在、すべての最新ブラウザでサポートされていないため、両方を使用するか、report-uri
のみを使用することをおすすめします。
コンテンツが CSP に違反している場合、ブラウザから、構成されている宛先にレポートが送信されます。これらのレポートを処理するアプリケーションがこのリンク先で構成されていることを確認してください。
HTTP ヘッダーで CSP を定義する
CSP は、メタタグで次のように定義できます。
<meta http-equiv="Content-Security-Policy" content="script-src 'none'">
ただし、可能であれば、HTTP レスポンス ヘッダーで CSP を定義する必要があります。メタタグの前に挿入すると、CSP がバイパスされます。また、frame-ancestors
、sandbox
、およびレポートは、メタタグ CSP でサポートされていません。
CSP に下位互換性があることを確認してください
すべてのブラウザが CSP のノンス/ハッシュをサポートしているわけではないため、ポリシーに準拠していないブラウザの代替手段として unsafe-inline
を追加することをおすすめします。ブラウザでノンス/ハッシュがサポートされている場合、unsafe-inline
は無視されます。
同様に、strict-dynamic
は一部のブラウザではサポートされていません。ポリシーに準拠していないブラウザに対しては、代替手段として許可リストを設定することをおすすめします。strict-dynamic
をサポートするブラウザでは、許可リストは無視されます。
厳格な CSP の作成方法
以下は、厳格な CSP とノンスベースのポリシーを使用する例です。
CSP:
script-src 'nonce-random123' 'strict-dynamic' 'unsafe-inline' https:;
object-src 'none';
base-uri 'none';
report-uri https://reporting.example.com;
HTML:
<script nonce="random123" src="https://trusted.example.com/trusted_script.js"></script>
random123
は、ページが読み込まれるたびにサーバーサイドで生成される base64 文字列です。最新のブラウザでは、unsafe-inline
と https:
はノンスと strict-dynamic
があるため無視されます。厳格な CSP の採用について詳しくは、厳格な CSP ガイドをご覧ください。
Lighthouse と CSP Evaluator を使用して、潜在的なバイパスの有無をチェックできます。既存のページが壊れるリスクなしに新しい CSP をテストする場合は、ヘッダー名として Content-Security-Policy-Report-Only
を使用し、レポート専用モードで CSP を定義します。これにより、report-to
と report-uri
で構成したレポート宛先に CSP 違反が送信されますが、CSP は実際に適用されません。