Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: csp nonce support #14653

Closed
wants to merge 5 commits into from
Closed

Conversation

sapphi-red
Copy link
Member

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
    • fix: add style nonce to comply with content security policy (fix #11862) #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.
    • fix(CSP): nonce support #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 (#11864 (comment)) 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
  • New Feature
  • Documentation update
  • Other

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

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines and follow the PR Title Convention.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • 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 sapphi-red added enhancement New feature or request p2-to-be-discussed Enhancement under consideration (priority) labels Oct 16, 2023
@q7314568
Copy link

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.

@tvongaza
Copy link

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.

@gregtwallace
Copy link
Contributor

gregtwallace commented Oct 31, 2023

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}" >

@ghiscoding
Copy link
Contributor

ghiscoding commented Nov 7, 2023

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

@sapphi-red
Copy link
Member Author

@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).

@tvongaza
Copy link

tvongaza commented Nov 8, 2023

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
Copy link

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.

#11864 (comment)
#5218 (comment)

@Jay-Mason
Copy link

Jay-Mason commented Feb 9, 2024

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.

@sapphi-red sapphi-red mentioned this pull request Feb 28, 2024
9 tasks
@sapphi-red
Copy link
Member Author

superseded by #16052

@sapphi-red sapphi-red closed this Feb 28, 2024
@sapphi-red sapphi-red deleted the feat/csp-support branch February 28, 2024 16:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request p2-to-be-discussed Enhancement under consideration (priority)
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Issue setting strict CSP in dev nonce tag in __vitePreload (CSP)
6 participants