サイト脆弱性をチェックしよう! -- 第20回:CSP(Content Security Policy)
<目次>
Content Security Policyとは
Content Security Policyはブラウザ上でのコンテンツ読み込みを制限してクロスサイトスクリプティング攻撃(XSS)等のリスクを軽減する仕組みである。
WebサーバーがWebページを応答する際、HTTPレスポンスにContent-Security-Policyヘッダーを設定することで、インラインスクリプト(HTML文書内の<Script>タグを使って、直接文書内にJavaScriptを埋め込む方法)やevalなどを禁止したり、ソースの参照先を制限することで信頼できるリソースのみを使用することができる。
Content Security Policyは当初XSSの攻撃を軽減するために設計されたが、その後、クリックジャッキングなど他の形式の攻撃も軽減することが可能となった。
どのように設定する?
構文
Content-Security-Policyヘッダーは以下の構文で記載する。
Content-Security-Policy: <ポリシー>
ポリシーの部分は、
<ディレクティブ> <ソース>
の形式で適用したいコンテンツセキュリティポリシーを表すディレクティブから構成される文字列を設定する。
一つのディレクティブには一つまたは複数のソースも指定することができ、複数のソースを指定する場合は、
<ディレクティブ> <ソース> <ソース> <ソース>・・・
のように半角スペース区切りでソースを記載する。
複数のディレクティブを指定する場合は、
<ディレクティブ> <ソース>; <ディレクティブ> <ソース>; <ディレクティブ> ・・・
のように;(セミコロン)区切りで記載する。
ディレクティブ
ディレクティブは制御したいポリシーを指定する。
よく設定されるディレクティブは以下の通り。
default-src:リソースを取得する際のデフォルトポリシーを定義
script-src:JavaScript の有効なソースを定義
style-src:スタイルシートの有効なソースを定義
img-src:画像の有効なソースを定義
frame-ancestors:リソースを埋め込むことができる URL を制限
ソース
ソースは許可されるドメインやプロトコル、ポートなどを指定する。
ソース部分に指定する値について説明する。
<host-source>
ホスト名またはIPアドレスによるインターネットホスト
任意でURLスキームやポート番号を付けることもできる
設定例: http://*.example.com mail.example.com:443 https://test.example.com*
<scheme-source>
http:または https:のようなスキームを指定
data:スキームも指定できるが安全でないため非推奨
'self'
保護された文書が提供されたオリジンを同じURLスキームおよびポート番号で参照
'unsafe-eval' (非推奨)
文字列からコードを生成する eval() および同様のメソッドの利用を許可('unsafe-eval'がscript-srcディレクティブで指定されていなければevalはブロックされる)
'unsafe-hashes' (非推奨)
特定のインラインのイベントハンドラー(例えばonclickなど)を許可
'unsafe-inline' (非推奨)
インラインの <script> 要素、javascript: の URL、インラインイベントハンドラー、インライン <style> 要素のような、インラインリソースの使用を許可
'none'
空のセットを参照
ポリシーの設定例
default-src 'self'
すべてのコンテンツについて同一オリジン以外の接続を禁止
default-src 'self' *.hoge.jp
すべてのコンテンツについて同一オリジンに加え、指定したドメイン「hoge.jp」とそのすべてのサブドメインからの接続を許可
default-src 'self'; img-src *; media-src media1.com media2.com; script-src script.hoge.com
img-src *で任意のドメインからの画像読み込みを許可し、media-src media1.com media2.comで音声や動画は指定したドメインのみ許可し、script-src script.hoge.comでスクリプトは指定したサーバーのみ許可
default-src https:// test.example.com
HTTPSでドメインtest.example.com のみに制限
script-src https://example.com/
インラインのスクリプトやイベントハンドラーはブロックされる
以下のスクリプトはsrcの指定ドメインが許可されていないためブロックされ、読み込みや実行は行われない
<script src="https://test.example.com/js/library.js"></script>
frame-ancestors 'self' https://www.example.com
クリックジャッキング対策の設定例
同一オリジンに加え、指定した「https://www.example.com」とそのすべてのサブドメインのページ埋め込みを許可
Content-Security-Policyヘッダー導入時の注意点
Webアプリケーション本来の動作に影響を与えないようにする必要がある。
具体的な影響例:
・インラインのスクリプトやイベントハンドラーが動作せず通常の画面遷移ができない
・Google Analytics等の外部サービスが使用できない
・広告が表示されない
Content-Security-Policyヘッダーを導入する際には、スクリプト実行を許可するドメインの追加や、幾つかの挙動を例外的に許可する設定を足す必要がある。
まとめ
XSSの有効な対策はバリデーションとエスケープだが、その対策に不備があった場合の緩和策としてContent-Security-Policyは有効といえる。
ただし、Content-Security-Policyの導入はアプリケーションの動作に影響する可能性があるので、事前に導入しても問題ないことを確認する必要がある。