Content Security Policy(CSP)
概要
- GoogleTagManagerのカスタムHTMLタグ、カスタムJavaScript変数を制限するために調べた時のメモ。
基本仕様
- ホワイトリストを使用して許可する対象をクライアント(ブラウザなど)に指示する。
- ホワイトリストに設定されたリソースだけ実行およびレンダリングさせることができる。
- ホワイトリストはディレクティブで設定する
- デフォルトでインラインコードとeval()は有害とみなす
- 'unsafe-inline' もしくは 'unsafe-eval'で明示的に有効化する必要がある
設定方法
- HTTPヘッダー
Content-Security-Policy: [ディレクティブ] [オリジン] [オリジン]; [ディレクティブ] [オリジン] [オリジン]; ...
- metaタグ
<meta http-equiv="Content-Security-Policy" content="[ディレクティブ] [オリジン] [オリジン]; [ディレクティブ] [オリジン] [オリジン]; ...">
ディレクティブの書き方例
script-src https://host1.com https://host2.com;
オリジンの指定方法
名称 | 例 |
---|---|
スキーム | data:, https: |
ホスト名 | example.com |
完全修飾URI | https://example.com:443 |
ワイルドカード |
*://*.example.com:* スキーム、ポート、ホスト名の一番左端のみに限定 |
オリジンに指定できるキーワード
- これらのキーワードにはシングルクォーテーションが必要
キーワード | 説明 |
---|---|
'none' | 何も一致しない = 全て無効化 |
'self' | 現在のオリジンと一致する サブドメインは除外 |
'unsafe-inline' | インラインJavaScriptおよびCSSを許可する |
'unsafe-eval' | evalなどのtext-to-JavaScriptの仕組みを許可する |
ディレクティブについて
ディレクティブ | 説明 |
---|---|
script-src | スクリプト関連の権限を制限する |
base-uri |
<base> 要素に表示できるURLを制限する |
child-src | ワーカーと組み込みのフレームコンテンツのURLを制限する |
connect-src | XHR, WebSockets, EventSourceを経由して接続できるオリジンを制限する |
font-src | ウェブフォントを配信できるオリジンを制限する |
form-action |
<form> タグからの送信の有効なエンドポイントを制限する |
frame-ancestors | 現在のページに組み込める参照元を制限する<frame> ,<iframe> ,<embed> ,<applet> タグに適用される |
img-src | 画像を読み込み可能なオリジンを制限する |
media-src | 動画と音声を配信できるオリジンを制限する |
object-src | Flashなどのプラグインの種類を制限する |
plugin-types | ページで起動できるプラグインの種類を制限する |
report-uri | コンテンツセキュリティポリシーが違反された時にレポートを送信するURLを指定する |
style-src | スタイルシートのscript-srcに相当する |
upgrade-insecure-requests | ユーザーエージェントに支持してURLスキーマを書き直し、HTTPをHTTPSに変更する |
default-src | 未指定の-src ディレクティブの大半に対してデフォルトを定義する |
デフォルト
- デフォルトではディレクティブ に制限はない
- default-srcを設定することで、自動的に
-src
で終わるディレクティブがdefault-srcのオリジンに設定される
実装の詳細
- 使用するヘッダーによらずポリシーは
ページごとに定義される
インラインコードは有害とみなす
-
以下の2つだけではインラインスクリプトの注入に対処できない
- CSPは明確にホワイトリストに登録されたオリジンに基づいている
- 特定のリソースだけ受け入れてそれ以外を拒否する
-
以下を含むインラインスクリプトを完全に禁止する
- インラインイベントハンドラ
<a onclick="[JAVASCRIPT]">
- javascript: URL
-
適切な
addEventListener()
に置き換える必要がある -
どうしてもインラインスクリプトを使用したい場合はオリジンに
'unsafe-inline'
を指定するscript-src 'unsafe-inline';
CSP1の対応状況
- IE10でのサポートはかなり制限されている
CSP2でのみ使用できるオリジン指定
- nonce
- 暗号化された値を用意し、CSPとscriptタグに設定する
// CSPの設定
script-src 'nonce-1234567890'
<!-- HTMLの設定 -->
<script nonce="1234567890" >
alert('Hello');
</script>