marko-js / webpack

A loader for marko files and a plugin for universal bundling
MIT License
13 stars 4 forks source link

Add CSP nonce to the rendered script #22

Closed MiloCasagrande closed 4 years ago

MiloCasagrande commented 4 years ago

Version: 2.0.0

Description

When using CSP headers with a CSP nonce value, markojs itself correctly sets the nonce attribute of the script tag for the various resources.

The issue is with the dynamically loaded script from marko/webpack that does not contain the nonce attribute, and the browser will not execute it.

Why

We rely on CSP headers in our webapps, but we have to fallback to unsafe-inline in order to correctly use marko/webpack.

Possible Implementation & Open Questions

webpack has a "feature" where setting the variable __webpack_nonce__ in the JS entry point, it will add the nonce attribute to the scripts, not sure if that's something that can be leveraged here.

It would be great to have a more detailed approach on how the CSP headers are set as well, with maybe the possibility to compute the sha of the code instead on relying on the nonce value.

Is this something you're interested in working on?

Maybe, with guidance.

DylanPiercey commented 4 years ago

This should be straight forward for the scripts inlined.

Do you happen to know if scripts added dynamically via js also require the nonce? It seems webpack is doing that here https://github.com/webpack/webpack/pull/3210/files#diff-82578d379e84f28902072d7b5efc5be0R43

MiloCasagrande commented 4 years ago

Do you happen to know if scripts added dynamically via js also require the nonce? It seems webpack is doing that here https://github.com/webpack/webpack/pull/3210/files#diff-82578d379e84f28902072d7b5efc5be0R43

It would be better yes, since those scripts would need to be trusted as well.

There is also a CSP level 3 option for the script-src directive called strict-dynamic that states that dynamically loaded scripts from an already allowed script are safe; but I'm not sure how much support there is for CSP level 3 out there though.

DylanPiercey commented 4 years ago

This is now fixed in 3.0.0. You must also upgrade Marko to 4.18.47 and then you can pass a cspNonce as a Marko global and it will be picked up here (as well as other scripts output by Marko).

Eg:

template.render({ $global: { cspNonce: "..." } });