CSP strict-dynamicとnonce:信頼伝播とunsafe-evalの違い
nonceによる信頼伝播、別個のunsafe-eval許可、Report-Only導入とCSPの限界を説明します。
発行・訂正窓口:infostoa · 編集基準
この記事の個別の執筆者・専門査読者の情報は提供されていません。
strict-dynamicはnonceまたはhashで許可されたscriptが動的に追加するscriptにも信頼を引き継ぐCSP規則です。対応browserではhost許可listを増やす代わりに、許可したbootstrap scriptとloaderを中心にpolicyを設計できます。CSP Level 3仕様とweb.devのstrict CSP guideを併せて読むと適用範囲が分かります。
nonceで許可する起点とloader
serverはresponseごとに予測困難なnonceを生成し、CSP headerと実行を許可する<script>要素に同じ値を設定します。strict-dynamic対応browserはnonce/hashで許可されたscriptと、それが動的に追加したnon-parser-inserted scriptを信頼できます。この場合、hostやschemeの許可listは主な判断基準ではなく互換性fallbackとして扱われることがあります。
Content-Security-Policy: script-src 'nonce-{responseごとの乱数}' 'strict-dynamic'; object-src 'none'; base-uri 'none'
これは一つのkeywordであらゆる脅威を防ぐという意味ではありません。信頼されたloaderが未検証のuser inputをscript.srcに設定すれば、意図しないcodeを読み込む可能性があります。loaderが参照するURL、manifest、設定も実行境界として確認します。
`'unsafe-eval'`は別の実行許可
strict-dynamicと'unsafe-eval'は別の動作を制御します。script-srcまたはfallbackで'unsafe-eval'を許可すると、eval()、Function() constructor、文字列を受け取るsetTimeout()やsetInterval()などでJavaScriptを動的評価できます。strict-dynamicを加えてもこの許可が自動で解除されるわけではありません。runtimeやbuild成果物が文字列評価に依存する箇所を探し、削除するか必要性を別に判断します。
nonce/hash policyは対応browserで通常のinline scriptを制限しますが、CSPがHTML injection欠陥を修正するわけではありません。responseごとに新しいnonceを作り、同じpageで実行許可を得たcodeにも隠れた秘密だとは扱わないでください。安全なDOM APIとcontext別output encodingで注入原因を直し、信頼済みloaderの入力も検証します。
Report-Onlyで段階導入する
最初から強制するとinline event handlerや動的に追加するscriptが動かなくなることがあります。まずContent-Security-Policy-Report-Onlyで違反を集め、必要な処理をevent listenerへ移し、通常の画面動作とscript読み込み経路を確認します。その後段階的に強制し、reportを継続して確認します。違反報告がないことはXSS欠陥がない証明ではありません。
strict-dynamicを理解しない古いbrowserではfallbackの動作が異なります。web.devは一部旧browser向けにhttps:などのfallbackを検討する方法を説明しますが、そのbrowserでは信頼範囲が広がる場合があります。実際のbrowser versionとapplicationを組み合わせて試してください。
強制前の確認
- serverはresponseごとに予測困難なnonceを生成しているか。
- nonceは実行を許可するscriptだけに付き、headerの値と一致するか。
- 信頼済みloaderが攻撃者制御の値をscript URLにしないか。
'unsafe-eval'の利用箇所を別途確認したか。- Report-Only報告と古いbrowserのfallbackを実画面で試したか。
CSPはbrowserのscript実行を制限する防御層の一つです。authentication、authorization、安全なoutput処理、脆弱なcodeの修正、その他のsecurity controlを置き換えません。