コンテンツセキュリティポリシー(Content Security Policy)はアクセス、利用できるリソースを限定することで、XSS(クロスサイトスクリプティング)やデータインジェクションなど、クライアントサイドにおける脅威の影響を軽減できる仕組みです。
この記事ではコンテンツセキュリティポリシーの基本と、その書き方を解説します。
Monacaアプリにおけるコンテンツセキュリティポリシー
コンテンツセキュリティポリシーは最初に読み込まれるファイルに記述します。つまり www/index.html
になります。このファイルを開くと、次のような記述があるのが分かるはずです。これがコンテンツセキュリティポリシーです。
<meta http-equiv="Content-Security-Policy"
content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:;worker-src * blob:"
>
コンテンツセキュリティポリシーの内容
指定できるリソースの種類
コンテンツセキュリティポリシーは利用するリソースの種類と、それを利用できるデータ元という形で記述します。つまり上記の例で言えば、リソースの種類は次の2つになります。
- default-src
- worker-src
他に以下のようなリソースがあります。default-srcが指定されていることで、すべてのリソースに対してdefault-srcの条件が適用された上で、各リソースの条件に変更を加えられます。
また、worker-srcは、Worker,SharedWorker, ServiceWorkerスクリプトの有効なソースを指定します。
- img-src
画像 - media-src
音声や動画 - script-src
JavaScript の scriptタグ - child-src
iframeやframeタグ、そしてその中で読み込まれるworker - connect-src
fetchやXMLHttpRequest、WebSocketなどJavaScriptを介して読み込まれる外部リソース - font-src
フォント - form-action
フォーム送信 - frame-ancestors
frame/iframe/object/embed/applet - frame-src
iframe/frame - manifest-src
manifest - object-src
object/embed/applet - script-src-attr
HTML中のonclickなど - script-src-elem
script - style-src
style - style-src-attr
HTML中のstyle要素 - style-src-elem
style
指定できるリソース
コンテンツセキュリティポリシーは次のように記述します。リソースは複数種類指定できます(スペースで区切ります)。最後に ;
を書いて、次のリソースを指定します。
(指定できるリソースの種類) (リソース1) (リソース2) (リソース3);
リソースの種類によって直接書けるものと、シングルクォートで囲む必要があるものがあります。
直接書けるリソース
直接指定できるリソースは下記があります。URLは * を使ってワイルドカードにすることもできます。
- URL
- 例
.example.com
https://.example.com
https://api.example.com
- 例
- *(アスタリスク)
- スキーム
- http:
- https:
- data:
- blob:
- content:
- gap:
- mediastream:
- filesystem:
文字列で指定するリソース
文字列で指定するリソースは次の通りです。シングルクォートで囲んでください。
- self
同じURLスキーム、ポート番号のみ - unsafe-eval
evalの利用を許可 - unsafe-hashes
インラインでのイベントハンドラー記述を許可 - unsafe-inline
javascript: やインラインでのscriptタグの許可 - none
許可しない場合 - nonce-<base64-value>
一時的に許可されるノンスを使って、さらにセキュアに実行対象を絞り込みます - <hash-algorithm>-<base64-value>
上記に似ていますが、さらにハッシュ化アルゴリズムを指定します - strict-dynamic
マークアップ内のスクリプトを明示的に信用する
Monacaアプリのデフォルトコンテンツセキュリティポリシーを読み解く
では、最初に戻ってMonacaアプリに記述されているコンテンツセキュリティポリシーは、次のように記述されています。
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:;worker-src * blob:">
まず、すべてのリソースに対して次のように設定されています。
- *
すべての外部コンテンツ - 'self'
ローカルファイル - 'unsafe-inline'
インラインでの記述 - 'unsafe-eval'
evalを許可 - data:
data:の許可 - gap:
iOS用(プラグイン) - content:
Android用(プラグイン)
そしてWeb Workerに対しては、次のように定義しています。
- *
すべての外部コンテンツ - blob:
blobでの適用許可
他は必要があれば、開発者自身が追加可能です。
まとめ
コンテンツセキュリティポリシーを適切に利用することで皆さんのアプリは安心、安全なものになります。特にimg-srcやscript-srcはインシデントに繋がりやすいので、慎重に設定することをお勧めします。