You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Provide a way to add a nonce to the inline webpack script #5144
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.
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.
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 preferredContent-Security-Policy header, which support frame-ancestors, report-uri and sandbox) and say one of:
@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?
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.
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/).
@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)?
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.
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.
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.
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.
Activity
iansu commentedon Sep 27, 2018
Can the nonce just be a static identifier or does it have to be generated dynamically?
caedmon commentedon 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 commentedon Sep 27, 2018
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 preferredContent-Security-Policyheader, which supportframe-ancestors,report-uriandsandbox) and say one of:Timer commentedon Sep 27, 2018
Does the
index.htmlcontain anything specifying that it's CSP'd? Is there a way we could "know" to not inline the runtime, barring configuration?caedmon commentedon 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 commentedon 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 commentedon Sep 28, 2018
That would certainly take care of my requirement, but I'm also not familiar with best practices here.
Timer commentedon Oct 1, 2018
Since this is an edge case, we recommend you write a
postbuildscript that removes the inline script and switches it back to the runtime chunk. You can find the runtime chunk viaasset-manifest.json, orglobby. Whatever suits you.#5184 will make sure this file gets emitted to disk (
build/).PerfectPixel commentedon Oct 4, 2018
@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 (likereact-scripts --no-inline-scripts)?gaearon commentedon 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 commentedon Oct 4, 2018
@gaearon I like that. If no other scripts pop-up that solution should work 👍
caedmon commentedon 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 commentedon Oct 4, 2018
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 commentedon Oct 4, 2018
@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 commentedon 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.