2

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 !

Doubidou
  • 1,573
  • 3
  • 18
  • 35

1 Answers1

3

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'>

granty
  • 7,234
  • 1
  • 14
  • 21
  • Okay thanks ; I think it makes sense, following the current SRI draft. The main "resource" is the style fetched and not the attribute's content. But, even the official draft says it works with – Doubidou Sep 21 '20 at 05:05
  • I has expanded my answer a little bit to avoid misunderstanding or misleading. SRI works separately and independently from CSP, but but CSP could use *integrity=* attribute to allow ` – granty Sep 21 '20 at 12:18