vite_ruby icon indicating copy to clipboard operation
vite_ruby copied to clipboard

Content security policy for development not working when nonces enabled

Open KieranP opened this issue 8 months ago • 1 comments

  • [x] I have tried upgrading by running bundle update vite_ruby.
  • [x] I have read the [troubleshooting section] before opening an issue.

Description 📖

With the following in the Rails content_security_policy.rb:

Rails.application.configure do
  config.content_security_policy_nonce_generator = ->(_request) { SecureRandom.base64(16) }

  config.content_security_policy do |policy|
    [SNIP]

    if Rails.env.development?
      policy.style_src(*policy.style_src, :unsafe_inline)
      policy.script_src(*policy.script_src, :unsafe_eval, "http://#{ViteRuby.config.host_with_port}")
      policy.connect_src(*policy.connect_src, "ws://#{ViteRuby.config.host_with_port}")
    end
  end
end

styles are broken in development. Getting the following browser console errore:

Content-Security-Policy: Ignoring “'unsafe-inline'” within style-src: nonce-source or hash-source specified
Content-Security-Policy: The page’s settings blocked an inline style (style-src-elem) from being applied because it violates the following directive: “style-src 'self' https: 'unsafe-inline' 'nonce-hlKBeGISpbxAy7igRiyz2w=='”

It appears that, if the CSP contains a nonce, then unsafe-* declarations are ignored. And because of this, all the

When I comment out content_security_policy_nonce_generator, then everything works as expected.

Reproduction 🐞

Please provide a link to a repo that can reproduce the problem you ran into.

Vite Ruby Info

Run bin/rake vite:info and provide the output:

bin/vite present?: true
vite_ruby: 3.9.2
vite_rails: 3.0.19
rails: 8.0.2
ruby: ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24]
node: v22.14.0
yarn: 4.8.1

installed packages:
work@ /Volumes/Work
├─┬ @storybook/[email protected]
│ ├─┬ @storybook/[email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
├─┬ @sveltejs/[email protected]
│ ├─┬ @sveltejs/[email protected]
│ │ └── [email protected] deduped
│ ├── [email protected] deduped
│ └─┬ [email protected]
│   └── [email protected] deduped
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├── [email protected]
└─┬ [email protected]
  ├─┬ @vitest/[email protected]
  │ └── [email protected] deduped
  ├─┬ [email protected]
  │ └── [email protected]
  └── [email protected]

KieranP avatar Apr 14 '25 22:04 KieranP

Did a bit more digging and found https://github.com/ElMassimo/vite_ruby/pull/444 - Vite looks for different meta tag in order to add nonce onto inject style tags.

Added <meta property="csp-nonce" nonce="<%= content_security_policy_nonce %>" /> and now things are working.

Perhaps vite_ruby could override rails csp_meta_tag in order to add both meta tags needed:

    <meta name="csp-nonce" content="<%= content_security_policy_nonce %>" />
    <meta property="csp-nonce" nonce="<%= content_security_policy_nonce %>" />

KieranP avatar Apr 14 '25 23:04 KieranP