Currently any HTML file served as a static file will not run any JS, as we do not inject nonces in static files.
We should provide a way to make this work.
Proposal
We can have the htmlinject plugin (or a separate one) expose a function that accepts a trusted source or an embedded FS and performs two checks:
1) Validates that all scripts are inline (<script src= doesn't work with hashes on safari and inline event handlers hashes are not widely supported)
2) Extract hashes and pre-computes the arguments to pass to the CSP plugin in order for stuff to work (e.g. strict-dynamic will likely be necessary in these cases).
Alternative
Use nonces: when we load the static files we put placeholders for nonces, and we bytes.Replace the placeholder when we serve them. This is secure as static content can't contain injections, but nullifies caching capabilities.
Potential improvement
We apply the proposal above, but when we encounter a script that is not inline we rewrite it as an inline script that adds a new script element to the dom, and use the hash for the loader in CSP. The loader script could even be just one loader to make this more efficient, like this tool does, and we could enhance this to carry over async attributes instead of defaulting to false.
Example:
When we see:
<script src="foo.js"></script>
We render:
<script>
var s = document.createElement('script');
s.src = "foo.js";
s.async = false;
document.body.appendChild(s);
</script>
And the hash for that script would be easy to compute.
Issue
Currently any HTML file served as a static file will not run any JS, as we do not inject nonces in static files.
We should provide a way to make this work.
Proposal
We can have the htmlinject plugin (or a separate one) expose a function that accepts a trusted source or an embedded FS and performs two checks: 1) Validates that all scripts are inline (
<script src=
doesn't work with hashes on safari and inline event handlers hashes are not widely supported) 2) Extract hashes and pre-computes the arguments to pass to the CSP plugin in order for stuff to work (e.g. strict-dynamic will likely be necessary in these cases).Alternative
Use nonces: when we load the static files we put placeholders for nonces, and we bytes.Replace the placeholder when we serve them. This is secure as static content can't contain injections, but nullifies caching capabilities.
Potential improvement
We apply the proposal above, but when we encounter a script that is not inline we rewrite it as an inline script that adds a new script element to the dom, and use the hash for the loader in CSP. The loader script could even be just one loader to make this more efficient, like this tool does, and we could enhance this to carry over
async
attributes instead of defaulting tofalse
. Example:When we see:
We render:
And the hash for that script would be easy to compute.