2021-1-14

Content-Security-Policyのメモ

雑な技術メモ

概要

スクリプトや画像、iframeなどのリソースの読み込みをドメイン単位で制限出来る仕組み。

設定方法

HTTPレスポンスヘッダ

Content-Security-Policy: script-src 'self';img-src https://example.com;

metaタグ

<meta http-equiv="Content-Security-Policy" content="script-src 'self';img-src https://example.com;">

構文

[ディレクティブ] [対象]; [ディレクティブ] [対象] [対象]; ...

例えば、

script-src 'self'; img-src 'self' https://example.com; ...

みたいな。'self' は自身のドメインのこと。この例でいうとスクリプトは自身のドメインのみ、画像は自身のドメインと https://example.com が提供するもののみ許可される。指定されていないディレクティブに関するもの(今回の場合CSSなど)は全て許可される。

script-src を設定すると一緒にインラインスクリプトや eval も禁止される模様。これを解除するには unsafe-inlineunsafe-eval を使う方法があるが、基本やらないほうがいい。

また、デフォルトの設定として default-src を使用することも出来る。

default-src 'none'; img-src 'self';

この場合、自身のドメインから提供される画像は許可されるが、それ以外のリソースは全て禁止される。自身のドメインから提供されているスクリプトも禁止。default-src を雑に設定してしまうとWEBサイトの動作に支障が出るので注意が必要。

CSPのテスト

Content-Security-Policy-Report-Only というHTTPヘッダを使えば、実際の動作に影響することなくコンソールへのエラー出力のみさせることが出来る。

CSPは非常に強力なため事前にこれを使って必要なものが禁止されていないかチェックする期間を設けたほうが良さそう。

チェックの際には report-uri というディレクティブを活用すると良さそう。

Content-Security-Policy: default-src 'self'; report-uri http://example.com/report/

って感じで書いておくと。 http://example.com/report/ に対してレポートが送信される。送信されるデータはMDNに詳細が書かれているので参考にすればいい。ReportURIというそれ用のサービスもあるみたいなので、そっちを利用するのも良いかも。

実際自分はどうするか

理想的には default-src 'none' を設定した上でホワイトリスト形式でガチガチに縛るのがセキュリティ的にはいいんだろうけど、維持が大変そう。典型的な攻撃であるXSS対策のために、script-src を設定することから始めようと思った。

参考

MDNによるCSPの概要

MDNによるCSPの詳細、指定できるディレクティブが網羅されている

Content Security Policyを設定してウェブサイトをXSSから守る