個人のWebサービスでconfig.content_security_policy_report_only=trueを外し、CSP違反があった場合にブラウザエラーを発生させるようにしたところ、Sytem Specが軒並み落ちるようになり対応したのでやったことをメモ📝
事象
ブラウザエラーを見たところ、以下のようなCSP違反のログが多数出ていたので、
The source list for the Content Security Policy directive 'script-src' contains an invalid source: ''nonce-''. It will be ignored.
実際に返却されるhtmlを確認してみたのですが、scriptタグに設定されるnonceが空文字になっていました。
<script nonce="">
原因
Rails側のnonceの生成処理は以下のようになっているのですが、このrequest.sesionの参照処理時にテスト環境でだけ、#<ActionDispatch::Request::Session:0xd610 not yet loaded>となっており、sessionが未ロードの状態のため空文字が返ってしまっていた模様 🤔
Rails.application.configure do config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } end
テスト環境では実際にログインせずにcurrent_userをallow_any_instance_ofで返してるので、その辺の理由でcontent_security_policy_nonce_generator実行時点でsessionが未ロードの状態になってしまっているのかも(?)
解決策
以下のようにrequest.session[:init] = trueを実施し明示的にsessionを扱うことでロードさせるようにしたところ解決した。
Rails.application.configure do config.content_security_policy_nonce_generator = ->(request) { # NOTE: テスト実行時に以下となりSessionが取得できずnonceが空文字になりCSP違反が発生してしまうので強制的にロードする # #<ActionDispatch::Request::Session:0xd610 not yet loaded> # https://github.com/rails/rails/issues/10813#issuecomment-297204965 request.session[:init] = true request.session.id.to_s } end