Create-react-app: Provide a way to add a nonce to the inline webpack script

Created on 27 Sep 2018  路  15Comments  路  Source: facebook/create-react-app

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.

proposal

Most helpful comment

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

All 15 comments

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

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.

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:

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?

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

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

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)?

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

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

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.

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

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 https://github.com/facebook/create-react-app/issues/5288 so it doesn't get lost on this closed issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

oltsa picture oltsa  路  3Comments

Aranir picture Aranir  路  3Comments

fson picture fson  路  3Comments

stopachka picture stopachka  路  3Comments

onelson picture onelson  路  3Comments