Content-Security-Policy (CSP)
CSP は Cross Site Scripting (XSS) や data injection 攻撃を防ぐための HTTP の仕様です。
CSP を有効にするには、以下のいずれかを実施します。
-
HTTP header で
Content-Security-Policy
を返すContent-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com
-
meta
タグでContent-Security-Policy
を埋め込む<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
CSP directives
CSP の policy は、上記のように directive に続けて、空白区切りで値リストの記述を ;
区切りで複数記載していきます。
directive は Content の種類によって、以下の種類があります。
default-src
child-src
connect-src
font-src
frame-src
img-src
manifest-src
media-src
object-src
prefetch-src
script-src
style-src
worker-src
default-src
は特殊な directive で、対象のコンテンツの directive が定義されていなかった場合に、この値が使われます。
CSP による制約
CSP が有効な場合、 HTML 本体以外のリソースをロード・実行しようとしたときに制約が生じます。
例えば、 img-src https://*;
のように設定すれば、 HTTPS 以外の画像の読み込みを制限することができます。
script-src unsafe-inline
script-src
に 'unsafe-inline'
を指定することで、 inline scripts と inline event handlers の実行を許可できますが、モダンブラウザではこのオプションは推奨されません。
代わりに nonce もしくは hash を用います。
script-src nonce
nonce
は inline scripts と inline event handlers に対して、 whitelist 形式で CSP の許可を与える方法です。
まず実行を許可したい inline script の nonce
属性に、 BASE64 エンコードしたテキストを埋め込みます。
<script nonce="2726c7f26c">
var inline = 1;
</script>
上記スクリプトの実行を許可するには、 CSP の script-src の policy に、以下のように 'nonce-BASE64_VALUE'
の値を埋め込みます。
Content-Security-Policy: script-src 'nonce-2726c7f26c'
nonce はランダムな値を使えば OK ですから、生成は簡単です。たとえば、 PHP だと以下のように生成できます。
> echo base64_encode(random_bytes(20));
fUz9xyElzZh7x4XwbKkt2OdAhPs=
script-src hash
inline scripts の実行を許可する方法は、他にもあります。
スクリプト本体 (空白・改行を含む / <script>
タグは除く) 全体のハッシュ値 (sha256 or sha384 or sha512) を求めて、それに対して whitelist 形式で許可するやり方です。
例えば、以下の inline script の実行を許可したいとします。
<script>var inline = 1;</script>
まず、このスクリプト本体のハッシュ値 (BASE64 エンコードしたもの) を求めます。今回は Ruby でやってみます。
> require 'digest'
> Digest::SHA256.base64digest 'var inline = 1;'
=> "B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8="
そして、 CSP の script-src の policy で以下のように、ハッシュアルゴリズム名に続けて、生成したハッシュを埋め込めば OK です。
Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='
References
- Content Security Policy (CSP) - HTTP | MDN
- CSP: script-src - HTTP | MDN
- Content-Security-Policy - HTTP | MDN
- Content Security Policy (CSP) - Google Chrome
- CSP Evaluator
- CSP with Kirby - how to best generate a nonce? - Questions - Kirby Forum
- CSP (Content Security Policy) nonce-sourceについて調べてみた — A Day in Serenity (Reloaded) — PHP, FuelPHP, Linux or something