How to work with SRI hash and "onload" attribute

851 views Asked by At

Following Google Lighthouse recommandations to get a faster response for my website, I'm using this trick to post-load fonts:

<link as="style"
  href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&amp;display=swap"
  onload="this.onload=null;this.rel='stylesheet'"
  rel="preload">

But it fails because of my strict CSP rules, and I don't know how to add a sha384 hash for this "onload" attribute :/

I tried to get the onload content hash like this:

echo "this.onload=null;this.rel='stylesheet'" | openssl dgst | openssl enc -base64 -A

Output: npWtxZLLH7z2/zORM47igyJ5eTYuOl9qxzn4A632S7yMmMKBDHhL5ZHC6eBSxc/C

Then I add it on CSP SRI list, and refresh, but it fails with:

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'strict-dynamic' '[...list of other SRI hashes...]' sha384-npWtxZLLH7z2/zORM47igyJ5eTYuOl9qxzn4A632S7yMmMKBDHhL5ZHC6eBSxc/C 'unsafe-inline' http: https:". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

How to permit this inline "onload" little script without authorize all inline scripts ? Why my SRI doesn't work when I add it ? :(

Thanks !

1

There are 1 answers

2
granty On BEST ANSWER

Why my SRI doesn't work when I add it ? :(

It's explained here on example of style-src directive. With the script-src situation the same.

How to permit this inline "onload" little script without authorize all inline scripts ?

Move inline event handler of 'load' to a separate script like 'click' in this topic. Then it can be allowed by 'nonce-value' or 'sha256/sha384/sha512-value'.

Updated:

I wish to clarity changes to do (move inline handler to a separate script):

<link as="style" id="fonts"
  href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&amp;display=swap"
  rel="preload">

<script nonce="sever_generated_value"> // if 'nonce-value' used.
  // Or just calculate hash sha256 (or sha384/512) of this script
  // and insert it into 'script-src' as 'sha256-calculated_value' 
  fonts.addEventListener("load", function() {
     this.onload=null;
     this.rel='stylesheet';
     });
</script>

Such separate inline script can be allowed by 'nonce-value'/'hash-value'.

PS: Pls note that Content Security Policy does not support 'hash-value' via SRI for external style sheets. Is supported only for built-in <style>...</style>. For scripts the 'hash-value' is supported for both: buil-in <script>...</script> and external <script src='...' integrity='hash_here'>