skip to Main Content

I’m facing a problem since this morning with webapps deployed with Apps Script that used to works fine previously. Of course no changes has been made to justify this problem.

External scripts are not loaded from the HTML side, and a new error arise in the console.

In order to have a reproducible example:

Code.gs

function doGet() {

  var template = HtmlService.createTemplateFromFile('index');

  return template.evaluate()
                .setTitle('TEST')
                .addMetaTag('viewport', 'width=device-width, initial-scale=1')
                .setSandboxMode(HtmlService.SandboxMode.IFRAME)
}

index.html:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  </head>
  <body>
        <div id="title">Hello</div>
  </body>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

  <script>
    window.onload = function() {

      console.log('loaded');
      console.log($('#title').html());

    }
  </script>
</html>

Results in the console:

[ERROR] This document requires 'TrustedHTML' assignment. (jquery.min.js:2)

[ERROR] Uncaught TypeError: Failed to set the 'innerHTML' property on 'Element': This document requires 'TrustedHTML' assignment. (jquery.min.js:2)

[LOG] loaded

[ERROR] Uncaught ReferenceError: $ is not defined

The source problem appears to be the <script src='' loading jQuery. But I didn’t notice any troubleshoot coming from Google, is it a new restriction for Apps Script?

Screenshots:
projet/console

Error Sources

Network + CSP

7

Answers


  1. Your error suggests that the URL does not comply to your CSP. You have not changed your code – true, but your server has a CSP ruleset and according to that jQuery is refused. You will need to look into the response header of your main request as well as meta tags in your HTML to see what your CSP actually is. Then find where it was defined (either in server settings or meta tags or some custom code) and adjust it so jQuery will be allowed.

    Alternatively you can download the jquery script locally and link it locally.

    EDIT

    I have read about this further, particularly at https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML

    and this is particularly interesting, inspired from the link above:

    const escapeHTMLPolicy = trustedTypes.createPolicy("myEscapePolicy", {
      createHTML: (string) => string.replace(/</g, "&lt;"),
    });
    
    let el = document.getElementById("myDiv");
    const escaped = escapeHTMLPolicy.createHTML("<img src=x onerror=alert(1)>");
    console.log(escaped instanceof TrustedHTML); // true
    el.innerHTML = escaped;
    

    Of course, having the HTML of

    <div id="myDiv"></div>
    

    I tested the above and it turned out to be nonfunctional in FireFox and functional in Chrome.

    So you will need to see whether trustedTypes is supported at all:

    if (typeof trustedTypes === "undefined") {
        alert("Trusted types are not supported");
    } else {
        alert("Trusted types are supported");
    }

    Now, I would suggest that you could create a function that on the inside checks whether trustedTypes is supported at all and if so, then create a policy. Otherwise just create a function that has a method name. Then, you can call that function in any browser without worrying where it is supported and where not:

    function getEscapeHTMLPolicy() {
        if (typeof trustedTypes === "undefined") {
            return {
                createHTML: (string) => string.replace(/</g, "&lt;"),
            }
        } else {
            return escapeHTMLPolicy = trustedTypes.createPolicy("myEscapePolicy", {
                createHTML: (string) => string.replace(/</g, "&lt;"),
            })
        }
    }
    let escPol = getEscapeHTMLPolicy();
    
    window.addEventListener("load", function() {
        document.getElementById("mydiv").innerHTML = escPol.createHTML(`<p>foo</p>`);
    });
    <div id="mydiv"></div>
    Login or Signup to reply.
  2. I am getting the same error now this morning as well. It was literally working last night. 😡

    I agree, it appears to be the jquery addition that is not being accepted. Even though the error being thrown references "TrustedHTML", should the jquery script be loaded as a TrustedScript?

    Login or Signup to reply.
  3. Raised on the issue tracker already. Hopefully, will be something that is fixed on Google’s side soon

    https://issuetracker.google.com/issues/313466551

    Login or Signup to reply.
  4. I got the same issue. It is not only the external file error.

    Maybe they changed CSP for google appscript.

    I need it to be fixed urgently, please.

    This document requires ‘TrustedHTML’ assignment.
    Uncaught TypeError: Failed to set the ‘innerHTML’ property on ‘Element’: This document requires ‘TrustedHTML’ assignment.

    Login or Signup to reply.
  5. Google changed the CSP for the /iframedAppPanel path that hosts the addon content.

    The new CSP includes the require-trusted-types policy. Only Chrome recognizes this policy, so only Chrome users will be affected.

    The policy bans setting innerHTML to an unsanitized string.

    If you assign to innerHTML (or, if you use React’s dangerouslySetInnerHTML), your addon will be broken for Chrome users.

    To fix it, rewrite your addon to not do that. (Yes, it would be nice if Google gave a heads up that they were doing this. Welcome to building for Google’s ecosystem, I guess.)

    Login or Signup to reply.
  6. I’ve observed the issue seems to be related to recent changes in the Content Security Policy (CSP) by Google, particularly impacting the use of jQuery in AppScript. This issue has been affecting various developers, and you can find more details and ongoing discussions on the Google Issue Tracker here: Google Issue Tracker – CSP & jQuery Issue.

    From what i’ve found, this problem appears to be specific to Chromium-based browsers. In environments like Chrome and Edge, including their incognito modes, jQuery fails to function properly. However, I found that Firefox does not encounter this issue and works as expected.

    This browser-specific behavior suggests a workaround: if you’re experiencing problems with jQuery in your AppScript projects on Chromium-based browsers, try switching to Firefox as a temporary solution until a more permanent fix is implemented by Google.

    EDIT: found the following workaround. Put this in the very top of your HTML .

    <script>
      if (window.trustedTypes && window.trustedTypes.createPolicy) {
        window.trustedTypes.createPolicy('default', {
          createHTML: string => string,
          createScriptURL: string => string,
          createScript: string => string,
        });
      }
    </script>
    
    Login or Signup to reply.
  7. As per the Google Issue Tracker, here’s a workaround to put in the very top of your HTML <head>:

    <script>
      if (window.trustedTypes && window.trustedTypes.createPolicy) {
        window.trustedTypes.createPolicy('default', {
          createHTML: string => string,
          createScriptURL: string => string,
          createScript: string => string,
        });
      }
    </script>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search