0

I have an express demo site using google sign in button and I have recently added Helmet JS to make the server more secure with the right headers.

Without HelmetJS, the Sign in Button loads without any problem and is able to pick logged in user as well. However after enabling Helmet JS in index.js and setting the required Content Security Policies (CSP) in the Helmet configurations, the following 2 scenarios happen:

  1. Sign in Button loads, but doesn't work, with the following COEP error: enter image description here

To mitigate this, I added crossorigin="anonymous" to the script header like so:

    <script crossorigin="anonymous" src="https://accounts.google.com/gsi/client" async defer></script>

as advised here

  1. Doing this, however, leads to the following CORS error and the button doesn't load, since the client library is not loaded: enter image description here

I have gone through the following similar SO questions to no avail, I'm not sure if I'm missing something, since there is a lot to absorb for understanding COEP / CORP and others.

  1. Cross-Origin-Embedder-Policy: how to allow only certain domains?
  2. Helmet Express ERR_BLOCKED_BY_RESPONSE.NotSameOrigin 200
  3. Ressources not loaded after setting CSP and CORP headers using Helmet

The other options left is to disable COEP in Helmet, which I'm not sure is advisable. Please help, what exactly is the way forward for using COEP in such a scenario.

Thank you for your time!

hydroweaver
  • 109
  • 9
  • 1
    Helmet maintainer here. I'm not 100% sure about this issue, but I think disabling COEP in Helmet is probably the right call. See [this answer](https://stackoverflow.com/a/71904053/804100) to see how to do that. – Evan Hahn Apr 18 '22 at 23:29
  • Hi @EvanHahn, thanks, that's what I ended up doing and it worked! Thank you! – hydroweaver Apr 19 '22 at 04:49

1 Answers1

1

Try this configuration of the helmet library - pass the one in constructor:

const helmetOpts = {
   contentSecurityPolicy: {
      directives: {
        defaultSrc:["'self'", 'fonts.gstatic.com', 'fonts.googleapis.com', "accounts.google.com","ssl.gstatic.com"],
        scriptSrc: ["'self'", 'fonts.gstatic.com', 'fonts.googleapis.com', "accounts.google.com","ssl.gstatic.com"],
        styleSrc :["'self'",'fonts.gstatic.com','fonts.googleapis.com',"cdn.jsdelivr.net","accounts.google.com","ssl.gstatic.com"],
        imgSrc:["'self'",'fonts.gstatic.com','fonts.googleapis.com',"cdn.jsdelivr.net","accounts.google.com","ssl.gstatic.com"],
        connectSrc:["'self'","accounts.google.com","ssl.gstatic.com"],
        fontSrc:["'self'",'fonts.gstatic.com','fonts.googleapis.com',"accounts.google.com"],
        objectSrc:["'self'",'fonts.gstatic.com','fonts.googleapis.com',"cdn.jsdelivr.net","accounts.google.com","ssl.gstatic.com"],
        mediaSrc:["'self'"],
        frameSrc:["'self'",'fonts.gstatic.com','fonts.googleapis.com',"cdn.jsdelivr.net","accounts.google.com","ssl.gstatic.com"],
        sandbox:null,
        reportUri:null,
        childSrc:["self"],
        formAction:["'self'","accounts.google.com","ssl.gstatic.com"],
        frameAncestors:["'none'"],
        pluginTypes:null,
        baseUri:null,
        reportTo:null,
        workerSrc:null,
        manifestSrc:null,
        prefetchSrc:null,
        navigateTo:null,
      },
    },
    crossOriginEmbedderPolicy:{ policy: "credentialless" },
    crossOriginOpenerPolicy: { policy: "same-origin-allow-popups" },
    crossOriginResourcePolicy: { policy: "same-site" },
    //OriginAgentCluster:false,
     referrerPolicy: {
      policy: ["origin",],
    },
    StrictTransportSecurity:false,
   // XContentTypeOptions:false,
    XDNSPrefetchControl:false,
    //XDownloadOptions:false,
   // XFrameOptions:false,
   // XPermittedCrossDomainPolicies:false,
    xPoweredBy:false,
}
....
app.use(helmet(helmetOpts));
....