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

Provide a way to add a nonce to the inline webpack script #5144

Closed
caedmon opened this issue Sep 27, 2018 · 15 comments
Closed

Provide a way to add a nonce to the inline webpack script #5144

caedmon opened this issue Sep 27, 2018 · 15 comments
Milestone

Comments

@caedmon
Copy link

caedmon commented Sep 27, 2018

Version 2.0.0 adds an inline script, which causes a problem with more restrictive content security policies. One way to selectively allow this inline script would be to set a nonce on it, and then whitelist that nonce in the CSP.

I don't know what would be the best way to pass this nonce to the build.

@iansu
Copy link
Contributor

iansu commented Sep 27, 2018

Can the nonce just be a static identifier or does it have to be generated dynamically?

@caedmon
Copy link
Author

caedmon commented Sep 27, 2018

I'm not sure I understand your question. I don't need CRA to generate the nonce, but just to take a provided nonce and add it to the inline script tag.

@edmorley
Copy link

The server must generate a unique nonce for each response (spec), so a nonce based approach would have to be used in combination with custom server configuration, eg:
https://scotthelme.co.uk/csp-nonce-support-in-nginx/

The other option is to add the hash of the inline content to the policy:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Sources

However given that the webpack runtime chunk changes often (hence why inlining it makes sense), the hash based approach would still need either:
(a) integration with whatever is serving the content (so the hash could be fed back from webpack to wherever the headers are generated)
(b) use of the <meta> tag based CSP (rather than the preferred Content-Security-Policy header, which support frame-ancestors, report-uri and sandbox) and say one of:

@Timer
Copy link
Contributor

Timer commented Sep 27, 2018

Does the index.html contain anything specifying that it's CSP'd? Is there a way we could "know" to not inline the runtime, barring configuration?

@caedmon
Copy link
Author

caedmon commented Sep 28, 2018

@edmorley The unique nonce requirement does complicate things, especially for a static server. The hash approach does sound better, though I haven't been able to make it work so far. And there is the question of how to feed it back. Would it work to write it to a file in the build folder?

@Timer Are you suggesting to add something to index.html to signal that it will be CSP'd?

@Timer
Copy link
Contributor

Timer commented Sep 28, 2018

Yeah, we could look for <meta http-equiv="Content-Security-Policy" /> or something and abort inlining. I'm not familiar with best practices around this.

@caedmon
Copy link
Author

caedmon commented Sep 28, 2018

That would certainly take care of my requirement, but I'm also not familiar with best practices here.

@Timer
Copy link
Contributor

Timer commented Oct 1, 2018

Since this is an edge case, we recommend you write a postbuild script that removes the inline script and switches it back to the runtime chunk. You can find the runtime chunk via asset-manifest.json, or globby. Whatever suits you.

#5184 will make sure this file gets emitted to disk (build/).

@PerfectPixel
Copy link

@Timer We just ran into this issue and I read your comment about it. Having implemented a script like the one you suggested, we realised that this might be a rather fragile solution (searching for <script>...</script> and replacing it). Is there any reason against having a parameter for the build script that disables inlining of scripts (like react-scripts --no-inline-scripts)?

@gaearon
Copy link
Contributor

gaearon commented Oct 4, 2018

I think we should add an ID to that script. Then you can search by that ID and it should be robust enough.

@PerfectPixel
Copy link

@gaearon I like that. If no other scripts pop-up that solution should work 👍

@caedmon
Copy link
Author

caedmon commented Oct 4, 2018

What I ended up doing is writing a script that searches for the script and calculates its hash for inclusion in the CSP. But I agree either an ID or, if there may be other scripts in the future, maybe a class, would make it feel less fragile.

@sarah12345
Copy link

We are also having this issue. It is not an edge case for projects that care about security. I agree with @PerfectPixel that there should be an option to avoid inline scripts and instead reference it as a link. Otherwise, we should at least have an id.

@PerfectPixel
Copy link

@Timer @gaearon
Just to explore, I tried to make inlining the runtime chunk configurable and it was not super difficult. Maybe it is worth a look: https://github.com/PerfectPixel/create-react-app/commit/14584aac78e7275693c4b9893e21f3ec8b21922c

However, I understand that adding plugins conditionally is not the best way. Or filter missing plugins for that matter. Replacing a plugin with a noop-plugin could also be an option.

@Timer
Copy link
Contributor

Timer commented Oct 4, 2018

We'd like to avoid adding a configuration flag for this when you can easily patch it with a postbuild script. Let's move discussion to #5288 so it doesn't get lost on this closed issue.

@Timer Timer reopened this Oct 4, 2018
@Timer Timer closed this as completed Oct 4, 2018
@facebook facebook locked as resolved and limited conversation to collaborators Oct 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants