#️⃣

CSP hash値/nonce値について調べました

に公開

CSPの設定で、hash/nonceに関連するエラーが出たので、この機に理解しようと思います。

Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

CSP(Content Secutiry Policy)

サイト内で実行/表示できるリソース(script/imageなど)のホワイトリスト。安全だと保証できるコンテンツのみを許可し、悪意のあるスクリプトなどの実行を防ぐための設定です。

  • 例:
    • self(サイトのドメイン)とcinnamon.comだけ実行を許可する
    Content-Security-Policy: default-src 'self' cinnamon.com
    

許可する対象としてドメインだけではなく、hashやnonceを設定することができます。それぞれ具体的に、見ていきます↓↓。

hash

<script>または<style>リソースをハッシュ化した値を設定する事ができます。こんな感じ↓↓

Content-Security-Policy: 'sha256-xxxxxxxxxxxxbyC8SgSy5MtTSodPXcKSMs01U='

ブラウザがHTML読み込み時に、<script>または<style>があった場合、ハッシュ化し、CSPに設定されているハッシュ値と一致した場合のみ実行を許可します。

  • あらかじめ実行許可するスクリプトをハッシュ化して、CSPに設定する

  • 読み込み時に、<script>/<style>タグをハッシュ化して、照合する

ドメイン指定よりも、より厳密に実行するリソースを制限します。ドメイン指定の場合、許可したドメインのスクリプトは全部許可されますが、ハッシュ値指定の場合、たとえ信用できるドメインの場合でも設定したハッシュ値と異なる場合、実行が拒絶されます。内容が書き換えられていた場合も、ハッシュ値が変わるので、実行拒絶することができます。

nonce

のんす値。サーバー側で生成した、nonce-[base64エンコードされた文字列]を指定します。レスポンスごとに生成されるので、毎回異なる値になります。こんな感じ↓↓

Content-Security-Policy: 'nonce-Jz2paVZ8oZ5c2xPT1LhHyQ==';
  • リクエストのたびに、サーバー側でnonce値を生成し、<script>または<style>のnonce属性に生成したnonce値を設定

  • 読み込み時に、<script>/<style>タグのnonce属性の値と、CSPに設定されている値を照合

ハッシュ値では対応しにくい、スクリプトの内容が動的に変わる場合にも、nonce値の設定で対応することができます。nonce値が漏れても、毎リクエスト事にnonceを生成するので、悪意のあるスクリプトを実行することは難しいです。

また、railsでは簡単に実装できる仕組みが用意されています。

エラーについて

Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

CSPに、hash値/nonce値が設定されている場合、unsafe-inlineは無視されるというもの。
今回設定されていたCSPは、こんな感じでした↓↓。

Content-Security-Policy: 'self' 'unsafe-inline' www.googletagmanager.com 'sha256-xxxxxxxxxxJ3ZbEGF5xp5Q='

unsafe-inlineは、インラインのJavaScriptやCSSの実行を許可するということ。unsafe-とついていることからわかるように、悪意のあるスクリプトも実行される可能性があるということです!
そもそもunsafe-inlineを設定するのは、せっかくCSP設定している意味をなくしてしまうので、良くないです、、。unsafe-inlineとhash値/nonce値が同時に設定されている場合、より厳格に制限し、安全性の高いhash値/nonce値の設定が優先されるという、ごく自然な仕組みです。

まとめ

  • unsafe-inlineは指定するな

参考

Discussion