CSP Examples for Every Third-Party Service You’re Probably Using
Table of Contents
🔧 Validate Your CSP Policy
Copy a CSP example, deploy it, then verify it works with a real scan.
Verify with headertest.com →
🔧 Validate Your CSP Policy
Copy a CSP example, deploy it, then verify it works with a real scan.
Verify with headertest.com →🔧 Validate Your CSP Policy
Copy a CSP example, deploy it, then verify it works with a real scan.
Verify with headertest.com →🔧 Validate Your CSP Policy
Copy a CSP example, deploy it, then verify it works with a real scan.
Verify with headertest.com →The hardest part of implementing CSP isn’t understanding the directives — it’s figuring out which domains to whitelist for every third-party service your site uses. Each one needs specific domains in specific directives, and the documentation is scattered across different sites.
I’ve spent way too much time hunting down the exact domains for various services. Here’s everything in one place. These are tested, copy-paste ready, and include the domains most people miss.
How to Use These#
Each service below shows the CSP directives you need to add. Combine them into a single policy for your site. I’ve also included a combined “everything” policy at the bottom.
Google Analytics (GA4)#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com https://www.googletagmanager.com;
img-src 'self' data: https: https://www.google-analytics.com https://www.googletagmanager.com;
frame-ancestors 'none';
base-uri 'self'
Most people remember googletagmanager.com for the script but forget google-analytics.com for the background requests that GA4 makes for event tracking and reporting.
Google Tag Manager#
GTM is a container for other tags, which means it loads scripts dynamically. You need a more permissive policy:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com;
connect-src 'self' https://www.google-analytics.com https://www.googletagmanager.com https://stats.g.doubleclick.net;
img-src 'self' data: https: https://www.google-analytics.com https://www.googletagmanager.com https://stats.g.doubleclick.net;
frame-src 'self' https://td.doubleclick.net;
frame-ancestors 'none';
base-uri 'self'
Note stats.g.doubleclick.net — this is used by remarketing and conversion tracking. If you see violations mentioning doubleclick, add it. Also td.doubleclick.net for conversion tracking iframes.
Google Fonts#
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
img-src 'self' data: https:;
frame-ancestors 'none';
base-uri 'self'
Two domains, and people regularly forget the second one. fonts.googleapis.com serves the CSS file. fonts.gstatic.com serves the actual font files (woff2, woff, ttf). Without fonts.gstatic.com in font-src, your fonts will fail to load and the browser will use fallback fonts.
Stripe.js#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://js.stripe.com;
frame-src 'self' https://js.stripe.com https://hooks.stripe.com;
connect-src 'self' https://api.stripe.com;
img-src 'self' data: https:;
frame-ancestors 'none';
base-uri 'self'
Stripe uses iframes for card input fields (Stripe Elements). The frame-src is critical — without it, the payment form simply won’t render. Users will see a blank space where the card number field should be. hooks.stripe.com is used for Stripe’s 3D Secure authentication flow.
Intercom (Live Chat)#
Intercom is one of the more complex integrations I’ve dealt with:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://widget.intercom.io https://js.intercomcdn.com;
frame-src 'self' https://intercom-sheets.com https://www.intercom-reporting.com;
connect-src 'self' https://api-iam.intercom.io https://nexus-websocket-a.intercom.io wss://nexus-websocket-a.intercom.io;
img-src 'self' data: https: https://downloads.intercomcdn.com;
style-src 'self' 'unsafe-inline';
frame-ancestors 'none';
base-uri 'self'
Intercom uses WebSockets for real-time messaging. Without wss:// in connect-src, the chat widget will connect but messages won’t send or receive in real-time. The intercom-sheets.com iframe is used for product tours and surveys. The intercom-reporting.com iframe is used by Intercom’s own analytics.
Hotjar (Heatmaps and Session Recordings)#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://static.hotjar.com https://script.hotjar.com;
connect-src 'self' https://*.hotjar.com https://vc.hotjar.io wss://*.hotjar.com wss://vc.hotjar.io;
img-src 'self' data: https: https://static.hotjar.com;
frame-ancestors 'none';
base-uri 'self'
Hotjar uses WebSocket connections for session recordings. Without wss:// in connect-src, recordings will start but fail to transmit. The vc.hotjar.io domain is for their video compression service.
Plausible Analytics#
If you’re using Plausible instead of Google Analytics (good choice for privacy):
Content-Security-Policy:
default-src 'self';
script-src 'self' https://plausible.io;
connect-src 'self' https://plausible.io;
img-src 'self' data: https:;
frame-ancestors 'none';
base-uri 'self'
Much simpler than Google Analytics. One domain, one script, one connect endpoint. This is what privacy-friendly analytics looks like from a CSP perspective.
Cloudflare Web Analytics#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://static.cloudflareinsights.com;
connect-src 'self' https://cloudflareinsights.com;
img-src 'self' data: https:;
frame-ancestors 'none';
base-uri 'self'
Simple and clean. Two domains total.
Cookiebot (Cookie Consent)#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://consent.cookiebot.com https://www.googletagmanager.com;
style-src 'self' 'unsafe-inline' https://consent.cookiebot.com;
frame-src 'self' https://consentcdn.cookiebot.com;
connect-src 'self' https://consent.cookiebot.com;
img-src 'self' data: https:;
font-src 'self';
frame-ancestors 'none';
base-uri 'self'
Cookiebot injects an iframe for its consent UI banner. The consentcdn.cookiebot.com domain handles the cookie declaration page that opens in a modal or new tab.
hCaptcha#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://js.hcaptcha.com https://hcaptcha.com;
frame-src 'self' https://*.hcaptcha.com;
connect-src 'self' https://*.hcaptcha.com;
img-src 'self' data: https:;
frame-ancestors 'none';
base-uri 'self'
The wildcard *.hcaptcha.com in frame-src is necessary because hCaptcha loads the challenge from different subdomains depending on the challenge type.
Sentry (Error Tracking)#
Content-Security-Policy:
default-src 'self';
script-src 'self' https://browser.sentry-cdn.com;
connect-src 'self' https://*.sentry.io;
img-src 'self' data: https:;
frame-ancestors 'none';
base-uri 'self'
HubSpot#
HubSpot has forms, live chat, and analytics — each with different domain requirements:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://js.hsforms.net https://js.hs-scripts.com https://js.hs-analytics.net;
style-src 'self' 'unsafe-inline' https://js.hsforms.net;
frame-src 'self' https://forms.hsforms.com;
connect-src 'self' https://forms.hsforms.com https://api.hsforms.com;
img-src 'self' data: https: https://no-cache.hubspot.com;
frame-ancestors 'none';
base-uri 'self'
Matomo (Self-Hosted Analytics)#
If you’re self-hosting Matomo, you only need your own domain:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://matomo.yoursite.com;
img-src 'self' data: https: https://matomo.yoursite.com;
connect-src 'self' https://matomo.yoursite.com;
frame-ancestors 'none';
base-uri 'self'
The Combined Policy#
Here’s a starting point with the most common services. Remove what you don’t use:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com https://js.stripe.com https://js.hcaptcha.com https://browser.sentry-cdn.com;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
img-src 'self' data: https: https://www.google-analytics.com https://www.googletagmanager.com;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://www.google-analytics.com https://www.googletagmanager.com https://api.stripe.com https://*.sentry.io https://*.hcaptcha.com;
frame-src 'self' https://js.stripe.com https://hooks.stripe.com https://*.hcaptcha.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests