Skip to content
New issue

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

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

Already on GitHub? # 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
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Projects
None yet
Development

No branches or pull requests

7 participants