vite icon indicating copy to clipboard operation
vite copied to clipboard

feat: csp nonce support

Open sapphi-red opened this issue 2 years ago • 7 comments

Description

This PR adds CSP nonce support for dev and build.

  • In dev
    • CSS imports in JS: If any script tag or style/link[rel=stylesheet] tag has a nonce attribute, @vite/client will inject the style tag with that nonce value.
    • Injected script/style/link[rel=stylesheet] tags by transformIndexHtml: normal/post hook now can have access to ctx.nonce that contains a nonce attribute extracted from the HTML. Each plugins has the responsibility to inject the nonce tag if needed.
  • In build
    • preload function: If any script tag or style/link[rel=stylesheet] tag has a nonce attribute, it will add the link tag with that nonce value.
    • nonce values in HTML: the value would be preserved for usecases like replacing the value in the middleware (e.g. nginx)

close #9719 close #11862

  • Difference from
    • #11864: read the value from meta[property=csp-nonce] and use that when injecting style tag generated by CSS imports in JS
      • Requires a custom tag for declaring the nonce value. In my PR, Vite uses the nonce value that is already declared.
      • Works with different nonce value for script-src and style-src. In my PR, that is not supported unless there's a style tag in the HTML. If we add a fallback to obtain the value from meta[property=csp-nonce-style], we can support this case as well.
      • Doesn't handle injected tags by transformIndexHtml. My PR handles that.
      • Doesn't handle preload function. My PR handles that.
      • Works with backend integration. My PR also works.
    • #11958: adds a new option noncePlaceholder and inject that value in HTML when bundling
      • Adds a new option. In my PR, Vite uses the nonce value that is already declared.
  • Things to consider

TODO

  • [ ] Add a test case
  • [ ] Warn if there's multiple nonce values
  • [ ] Add docs

Additional context

This table (https://github.com/vitejs/vite/pull/11864#issuecomment-1716852907) was really helpful to think about the way to support CSP nonce. Thank you @justin-tay.


What is the purpose of this pull request?

  • [ ] Bug fix
  • [x] New Feature
  • [ ] Documentation update
  • [ ] Other

Before submitting the PR, please make sure you do the following

  • [x] Read the Contributing Guidelines.
  • [x] Read the Pull Request Guidelines and follow the PR Title Convention.
  • [x] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • [x] Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • [ ] Ideally, include relevant tests that fail without this PR but pass with it.

sapphi-red avatar Oct 16 '23 14:10 sapphi-red

Hi,thanks for this PR,i really need this feature,

does this fix for vite react too?

my project is using CSR with vite react,am urgent need this.

q7314568 avatar Oct 26 '23 15:10 q7314568

Great PR! I hope this is considered by the Vite team. Looking forward to some sort of dev-side CSP for style sheets landing, this would get us one step closer in having our dev & production CSP files identical.

tvongaza avatar Oct 28 '23 05:10 tvongaza

I think this is the most complete solution. What do you think about requiring the meta tag(s)? Essentially adding the meta tags is the configuration to inject the nonces. This prevents having to copy paste a bunch of nonces or placeholders in the .html file. Instead just editing 1 (or 2) meta tags updates everything accordingly. This also elminates the sniffing of existing elements other than the specific meta tags.

Default can be the specific nonce type, with fallback to unspecified version if the user does not want to separate them.

<meta property="csp.nonce" nonce="{some-val}" >
<meta property="csp.nonce.script" nonce="{some-other-val}" >
<meta property="csp.nonce.style" nonce="{some-val2}" >

gregtwallace avatar Oct 31 '23 03:10 gregtwallace

that would be really awesome to get this in time before the upcoming 5.0 official release 😉

ghiscoding avatar Nov 07 '23 16:11 ghiscoding

@q7314568 Without a non-static server, this PR won't be useful because you need to generate a nonce for each request.


@gregtwallace I think most of the case, there'll be only one script tag and one style tag. But I'll include this point in the team discussion. 👍


@ghiscoding This PR won't land in 5.0 as we're in the final phase of the release (kind a RC phase).

sapphi-red avatar Nov 08 '23 07:11 sapphi-red

Thanks for the update @sapphi-red. As this does encourage better application security practices, I hope it is prioritized post 5.0 release. While it just applies to dev mode, being able to align our development CSP closer to production one forces our team to be more thoughtful about our CSP settings in production, along with letting us catch CSP errors earlier in the process. I know we have already been bit by a change which worked in dev, but our stricter production CSP caused an error.

As a rails user, add my vote for making use of the meta csp-nonce tag as it is standard in those installs. See rails docs here: https://api.rubyonrails.org/classes/ActionView/Helpers/CspHelper.html

tvongaza avatar Nov 08 '23 21:11 tvongaza

Now that v5 is released, is there any updates on this security related improvement @sapphi-red ?

We continue to see folks running into this issue as building stricter CSPs becomes more common. Not being able to setup Vite development mode with the same nonce settings as production is the only blocker for folks to do so in many cases. I would hope a security related issue like this gets prioritized accordingly as we all try to build more secure web software together.

https://github.com/vitejs/vite/pull/11864#issuecomment-1857567464 https://github.com/vitejs/vite/discussions/5218#discussioncomment-7865651

tvongaza avatar Dec 15 '23 16:12 tvongaza

I have been monitoring this thread and I'm curious about Vite's support for CSP nonces. While there is a workaround provided by @schamberg97 in this issue, I'd like to know if official support will be added in the near future before implementing the workaround.

Edit: I've been working on a workaround to inject a Content Security Policy (CSP) with a nonce value into each server-side render of my application. I'm dynamically importing my application based on browser support and injecting it into a script tag with the nonce, which works well for the compiled JavaScript.

However, I've encountered an issue with CSS files that are also being imported. These CSS files do not receive the nonce when they are loaded into the page. This means I need to add another middleware layer to add the nonce value to the CSS files once they are added to the page (which is after the module has been called)... is it possible to get an update on when this feature will be implemented into Vite? Thank you.

Jay-Mason avatar Feb 09 '24 14:02 Jay-Mason

superseded by #16052

sapphi-red avatar Feb 28 '24 16:02 sapphi-red