最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - GoogleTagManager isnt working because of Content Security Policy - Stack Overflow

programmeradmin5浏览0评论

I'm having this error (on production) - I've changed like 20 versions of the csp headers based on responses from all over ther internet and the AI chatbots, so I'm becoming desperate regarding the headers format:

Refused to load the script '.js?id=GTM-{key}' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

I've edited multiple versions of the following csp headers in the middleware and in the next config file:

headers: [
          {
            key: 'Content-Security-Policy',
            value: `
              default-src 'self';
              script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.googletagmanager https://*.google-analytics https://*.cloudflareinsights;
              script-src-elem 'self' 'unsafe-inline' https://*.googletagmanager https://*.google-analytics https://*.cloudflareinsights;
              style-src 'self' 'unsafe-inline' ;
              img-src 'self' blob: data: https://*.google-analytics https://*.googletagmanager https://*.cloudflareinsights;
              font-src 'self' data: ;
              connect-src 'self' https://*.google-analytics https://*.analytics.google https://*.googletagmanager https://*.cloudflareinsights;
              frame-src 'self' https://*.googletagmanager;
              worker-src 'self' blob:;
              child-src 'self' blob:;
              object-src 'none';
              base-uri 'self';
              form-action 'self';
              frame-ancestors 'none';
              upgrade-insecure-requests;
            `.replace(/\s{2,}/g, ' ').trim(),
          },
        ],

But nothing is working (even with claude and chatgpt suggestions). Here is my layouts.jx file:

//other imports
import { GoogleTagManager } from "@next/third-parties/google";




export default async function RootLayout({ children }) {
  const headersList = headers();
  // Get user data from headers


  const nonce = headersList?.get("x-nonce") || "";


  return (
    <html lang="en">
      <GoogleTagManager gtmId="GTM-(Actual key)" nonce={nonce} />
      <body className={bodyClassName}>
        <noscript>
          <iframe
            src={`.html?id=(Actual key)`}
            height="0"
            width="0"
            style={{ display: "none", visibility: "hidden" }}
          />
        </noscript>



        <div className="wrapper ovh mm-page mm-slideout">
          <div>
            {children}
 
          </div>
        </div>

      </body>
    </html>
  );
}

Regarding the nonce, here is how I stored it in the middleware:

async function generateNonce() {
  const array = new Uint8Array(16);
  crypto.getRandomValues(array);
  return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
}


function applyHeaders(response) {

  const nonce = generateNonce();


  const securityHeaders = {
    'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
    'Pragma': 'no-cache',
    'Expires': '0',
    'Surrogate-Control': 'no-store',
    'X-Frame-Options': 'DENY',
    'X-Content-Type-Options': 'nosniff',
    'Referrer-Policy': 'strict-origin-when-cross-origin',
    'Permissions-Policy': 'camera=(), microphone=(), geolocation=()',
    'X-XSS-Protection': '1; mode=block',
    'Content-Security-Policy': `
      default-src 'self';
      script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.googletagmanager https://*.google-analytics https://*.cloudflareinsights;
      script-src-elem 'self' 'unsafe-inline' https://*.googletagmanager https://*.google-analytics https://*.cloudflareinsights;
      style-src 'self' 'unsafe-inline' ;
      img-src 'self' blob: data: https://*.google-analytics https://*.googletagmanager https://*.cloudflareinsights;
      font-src 'self' data: ;
      connect-src 'self' https://*.google-analytics https://*.analytics.google https://*.googletagmanager https://*.cloudflareinsights;
      frame-src 'self' https://*.googletagmanager;
      worker-src 'self' blob:;
      child-src 'self' blob:;
      object-src 'none';
      base-uri 'self';
      form-action 'self';
      frame-ancestors 'none';
      upgrade-insecure-requests;
    `.replace(/\s{2,}/g, ' ').trim()
  };
  Object.entries(securityHeaders).forEach(([key, value]) => {
    response.headers.set(key, value);
  });
  response.headers.set('x-nonce', nonce)

  return response;
}

I'm having this error (on production) - I've changed like 20 versions of the csp headers based on responses from all over ther internet and the AI chatbots, so I'm becoming desperate regarding the headers format:

Refused to load the script 'https://www.googletagmanager.com/gtm.js?id=GTM-{key}' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval' blob:". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

I've edited multiple versions of the following csp headers in the middleware and in the next config file:

headers: [
          {
            key: 'Content-Security-Policy',
            value: `
              default-src 'self';
              script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.googletagmanager.com https://*.google-analytics.com https://*.cloudflareinsights.com;
              script-src-elem 'self' 'unsafe-inline' https://*.googletagmanager.com https://*.google-analytics.com https://*.cloudflareinsights.com;
              style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
              img-src 'self' blob: data: https://*.google-analytics.com https://*.googletagmanager.com https://*.cloudflareinsights.com;
              font-src 'self' data: https://fonts.gstatic.com;
              connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com https://*.cloudflareinsights.com;
              frame-src 'self' https://*.googletagmanager.com;
              worker-src 'self' blob:;
              child-src 'self' blob:;
              object-src 'none';
              base-uri 'self';
              form-action 'self';
              frame-ancestors 'none';
              upgrade-insecure-requests;
            `.replace(/\s{2,}/g, ' ').trim(),
          },
        ],

But nothing is working (even with claude and chatgpt suggestions). Here is my layouts.jx file:

//other imports
import { GoogleTagManager } from "@next/third-parties/google";




export default async function RootLayout({ children }) {
  const headersList = headers();
  // Get user data from headers


  const nonce = headersList?.get("x-nonce") || "";


  return (
    <html lang="en">
      <GoogleTagManager gtmId="GTM-(Actual key)" nonce={nonce} />
      <body className={bodyClassName}>
        <noscript>
          <iframe
            src={`https://www.googletagmanager.com/ns.html?id=(Actual key)`}
            height="0"
            width="0"
            style={{ display: "none", visibility: "hidden" }}
          />
        </noscript>



        <div className="wrapper ovh mm-page mm-slideout">
          <div>
            {children}
 
          </div>
        </div>

      </body>
    </html>
  );
}

Regarding the nonce, here is how I stored it in the middleware:

async function generateNonce() {
  const array = new Uint8Array(16);
  crypto.getRandomValues(array);
  return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
}


function applyHeaders(response) {

  const nonce = generateNonce();


  const securityHeaders = {
    'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate',
    'Pragma': 'no-cache',
    'Expires': '0',
    'Surrogate-Control': 'no-store',
    'X-Frame-Options': 'DENY',
    'X-Content-Type-Options': 'nosniff',
    'Referrer-Policy': 'strict-origin-when-cross-origin',
    'Permissions-Policy': 'camera=(), microphone=(), geolocation=()',
    'X-XSS-Protection': '1; mode=block',
    'Content-Security-Policy': `
      default-src 'self';
      script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.googletagmanager.com https://*.google-analytics.com https://*.cloudflareinsights.com;
      script-src-elem 'self' 'unsafe-inline' https://*.googletagmanager.com https://*.google-analytics.com https://*.cloudflareinsights.com;
      style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
      img-src 'self' blob: data: https://*.google-analytics.com https://*.googletagmanager.com https://*.cloudflareinsights.com;
      font-src 'self' data: https://fonts.gstatic.com;
      connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com https://*.cloudflareinsights.com;
      frame-src 'self' https://*.googletagmanager.com;
      worker-src 'self' blob:;
      child-src 'self' blob:;
      object-src 'none';
      base-uri 'self';
      form-action 'self';
      frame-ancestors 'none';
      upgrade-insecure-requests;
    `.replace(/\s{2,}/g, ' ').trim()
  };
  Object.entries(securityHeaders).forEach(([key, value]) => {
    response.headers.set(key, value);
  });
  response.headers.set('x-nonce', nonce)

  return response;
}
Share Improve this question edited Jan 19 at 18:50 Drew Reese 203k17 gold badges234 silver badges266 bronze badges asked Jan 19 at 16:52 AliAbAliAb 5693 gold badges8 silver badges33 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

This page is your guide: https://developers.google.com/tag-platform/security/guides/csp.

Note that if you use Google Analytics with Signal you may have to add a lot of google domains, just follow the link. If you want to support all of them (all countries), you might have to add 187 domains to img-src and connect-src.

发布评论

评论列表(0)

  1. 暂无评论