🛡️ GA4 + Bluehost + Cloudflare: When Security Blocks Analytics

ModSecurity WAF Troubleshooting for WordPress

Your Google Analytics 4 tag is installed correctly but tracking zero data. Google Search Console works fine. You've deactivated every plugin, cleared every cache, and checked every Cloudflare setting. Here's what's actually happening — and why standard WordPress troubleshooting will never find it.

⏱️ 15 min diagnosis 🟠 Advanced 🛡️ Security + Analytics ✅ Self-Fixable

⚠️ Who This Guide Is For

You're on Bluehost, HostGator, or any Newfold Digital shared hosting with Cloudflare. Your GA4 tag is in the page source but shows zero traffic. You've already tried deactivating plugins, clearing cache, and checking Cloudflare settings. Nothing worked.

This guide identifies the invisible server-level cause that no standard WordPress troubleshooting will find.

The Symptoms

  • GA4 Measurement ID is in page source (correct)
  • Google Search Console verified instantly (works fine)
  • GA4 Realtime report shows zero users despite live traffic
  • Browser console shows: Refused to load the script 'https://www.googletagmanager.com/...'
  • Deactivating all plugins doesn't fix it
  • Purging all caches doesn't fix it
  • Pausing Cloudflare doesn't fix it

Why Google Search Console Works But GA4 Doesn't

Google Search Console

Works
  • Verifies via DNS TXT record
  • Data collected by Google crawlers (server-side)
  • No JavaScript execution required
  • Immune to Content-Security-Policy

Google Analytics 4

Blocked
  • Requires JavaScript tag to execute in browser
  • Loads script from www.googletagmanager.com
  • Sends data to www.google-analytics.com
  • Blocked by restrictive CSP headers

This distinction is critical: GSC is server-side (invisible to browser security policies), while GA4 is client-side (subject to every browser security restriction). If your server is sending a Content-Security-Policy header that only allows scripts from your own domain, GA4 will silently fail.

Step 1: Confirm CSP Is the Problem

1 Open your site in Chrome or Safari → Right-click → InspectConsole tab

Look for errors like:

Refused to load the script 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline' 'unsafe-eval'"

2 In DevTools → Network tab → Click on the main page request → scroll to Response Headers

Look for this header:

Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'self';

If script-src only allows 'self' and does NOT include https://www.googletagmanager.com, that's your problem.

3 Confirm it's server-level (not Cloudflare cache):

Visit https://yourdomain.com/wp-admin/admin-ajax.php in incognito. Check if the CSP header appears AND if cf-cache-status shows DYNAMIC. If yes to both, the header is being injected at the server level — not cached by Cloudflare.

✅ If you confirmed CSP is present

You've identified the root cause. Continue to Step 2 to understand where it comes from and Step 3 to fix it.

Step 2: Eliminate the Usual Suspects

Before contacting your host, verify the CSP isn't coming from something you control:

Check .htaccess

1 In cPanel File Manager, open .htaccess in your site root. Search for Content-Security-Policy. If it's not there, .htaccess is clear.

Check Plugins

2 Security plugins that can set CSP headers:

  • Really Simple Security (formerly Really Simple SSL)
  • Headers Security Advanced & HSTS WP
  • HTTP Headers
  • Security Headers

Deactivate any of these if active, purge cache, and retest. If the CSP persists, it's not a plugin.

Check mu-plugins

3 Navigate to wp-content/mu-plugins/. These run even when "deactivated." Open each file and search for Content-Security-Policy.

Check Cloudflare

4 In Cloudflare dashboard, check:

  • Rules → Transform Rules → Modify Response Header
  • Rules → Managed Transforms → "Add security headers"
  • Rules → Page Rules

⚠️ If You've Eliminated All of These

The CSP is being injected by ModSecurity — your hosting provider's Web Application Firewall that operates below WordPress, below PHP, and is invisible to you. You cannot find it in any file on your account.

Step 3: The Fix (Contact Your Host)

On shared hosting, you cannot access or modify ModSecurity rules yourself. You need your host to whitelist the rule.

1 Contact your hosting provider's support and provide this message:

"A ModSecurity rule is injecting a Content-Security-Policy header on every response from my account. This CSP blocks all external JavaScript including Google Analytics (www.googletagmanager.com) and Google Tag Manager. I've confirmed it's not in .htaccess, not from any plugin, and not from Cloudflare. It appears on uncached dynamic responses (cf-cache-status: DYNAMIC on admin-ajax.php). Please identify and whitelist the ModSecurity rule as a false positive, or remove the CSP header from the server configuration."

2 The support agent should:

  • Check ModSecurity audit logs for your domain
  • Identify the specific rule ID triggering the CSP injection
  • Whitelist it as a false positive for your account

Propagation can take 0-4 hours after whitelisting.

3 After propagation, verify the CSP header is gone:

  • Check response headers in DevTools (should no longer show Content-Security-Policy)
  • Check browser console (GA4 script errors should disappear)
  • Check GA4 Realtime report (should show active users within minutes)

💡 Alternative: Ask for a Modified CSP

If your host won't remove the CSP entirely, ask them to modify it to allow Google Analytics:

script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://www.google-analytics.com; connect-src 'self' https://www.google-analytics.com https://*.google-analytics.com https://*.analytics.google.com;

Step 4: The Self-Fix That Actually Works

If your host's support hasn't resolved the issue, there are likely two problems compounding — and both have self-service fixes once you have the right information.

Problem A: The Double-Cloudflare Layer

If you manage your own Cloudflare account (your nameservers point to Cloudflare), your traffic may be passing through two Cloudflare instances:

Browser → YOUR Cloudflare (you control) → Bluehost's hidden CF proxy → Apache/WordPress

Bluehost's infrastructure routes traffic through their own Cloudflare integration even when you use your own. Their layer issues JS challenges (cf-mitigated: challenge) that block all bots — including Google's analytics validation.

1 Detect the double-layer: Hit your A record IP directly:

curl -sI http://YOUR_CURRENT_A_RECORD_IP -H "Host: yourdomain.com" | grep -i "server:\|cf-mitigated"

If you see Server: cloudflare and cf-mitigated: challenge when hitting the IP directly, you have a double-CF layer.

2 Get your real Apache IP from support:

"What is my account's direct server IP address — the actual Apache/cPanel IP, not the Cloudflare proxy IP? I manage my own Cloudflare and need to point my A record directly to the server."

The IP they give you should be different from what's currently in your A record. Verify it:

curl -sI http://REAL_IP -H "Host: yourdomain.com" | grep -i "server:" # Should return: Server: Apache (NOT Server: cloudflare)

3 Update your A record in Cloudflare:

  • Cloudflare Dashboard → DNS → Edit the A record for your domain
  • Change the IP from the old proxy IP to the real Apache IP
  • Keep the orange cloud (Proxy) enabled — this is YOUR Cloudflare, which you control

This takes effect immediately on Cloudflare. Verify:

curl -sI https://yourdomain.com | grep -i "server:\|cf-mitigated" # Should return: server: Apache (NO cf-mitigated header)

✅ Result

Traffic now flows: Browser → Your Cloudflare → Apache directly. One CF layer that you control. No more bot challenges blocking Google.

Problem B: Override the ModSecurity CSP via .htaccess

Even after fixing the double-CF layer, the ModSecurity CSP header may still be present. On some Bluehost configurations, you can override it with .htaccess:

4 Add this to the very top of your .htaccess file (before WordPress rewrite rules):

# Override ModSecurity CSP - Allow Google Analytics & Tag Manager <IfModule mod_headers.c> Header unset Content-Security-Policy Header always unset Content-Security-Policy Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.googletagmanager.com https://*.google-analytics.com; connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; font-src 'self' data:; frame-ancestors 'self';" </IfModule>

5 Verify the CSP changed:

curl -sI https://yourdomain.com | grep -i content-security-policy

You should now see googletagmanager.com and google-analytics.com in the CSP header. If the old restrictive CSP is still there, the .htaccess override didn't work and you need support to whitelist the ModSecurity rule.

✅ Final Result

With both fixes applied, GA4 will validate immediately. Open Google Tag Manager → Tag Assistant and you should see "Google tag is already installed" with a green checkmark.

⚠️ What You're NOT Disabling

This fix does NOT disable ModSecurity itself. ModSecurity continues protecting against SQL injection, XSS attacks, and other threats. You're only replacing its overly-restrictive CSP header with one that still enforces security but explicitly allows Google Analytics domains. All other external scripts remain blocked.

Why This Is Happening in 2024-2026

This isn't a one-off bug. It's a systemic shift in how web security infrastructure operates.

The ModSecurity Governance Change

DateEventImpact
Jan 2024Trustwave transfers ModSecurity to OWASPCommercial quality control ends
Jul 2024Trustwave ends all commercial support (EOL)Hosts lose paid support channel for tuning
2022-2026CRS 4.x releases (30+ monthly updates)False positive rate nearly doubles
CRS 4.0WordPress exclusions removed from coreMust install separate plugin per application

The False Positive Rate

CRS 3.x (Previous)

15.2% FP Rate

1 in 7 legitimate requests flagged. WordPress exclusions bundled in core rule set. Tuned by Trustwave's commercial team.

CRS 4.x (Current)

29.7% FP Rate

1 in 3 legitimate requests flagged. WordPress exclusions removed from core. Community-maintained with monthly releases.

How ModSecurity Injects CSP Headers

ModSecurity has a documented feature called "CSP enforcement as virtual patching." When its rules detect what they believe is an XSS-vulnerable application, they inject a Content-Security-Policy header to restrict script execution in the browser.

This is working as designed — it's just triggering on a false positive. Your WordPress + Divi site pattern matched something in the rule set that ModSecurity interpreted as XSS-vulnerable, so it "protected" your site by blocking all external scripts.

⚠️ The Collateral Damage

The restrictive CSP doesn't just block GA4. It also blocks:

  • Google Tag Manager
  • Meta/Facebook Pixel
  • HubSpot tracking
  • WordPress Stats (stats.wp.com)
  • Divi theme animations from CDN
  • WP Accessibility plugin
  • Any third-party JavaScript whatsoever

Prevention: Long-Term Solutions

Option A: Server-Side Google Tag Manager

Run GTM on your own server/subdomain. Since the script loads from your domain, CSP can't block it.

  • Requires Google Cloud Platform or similar
  • Cost: ~$50-100/month for a container
  • Immune to CSP, ad blockers, and WAF interference

Option B: GA4 Measurement Protocol

Send analytics data server-to-server via API, bypassing the browser entirely.

  • No JavaScript required
  • Requires custom development or a WordPress plugin that supports it
  • Completely immune to client-side restrictions

Option C: First-Party Analytics Proxy

Use Cloudflare Workers to proxy the GA4 script through your own domain.

  • Script loads from yourdomain.com (allowed by CSP)
  • Data sent through your domain to Google's servers
  • Requires Cloudflare Workers (free tier available)

Option D: Server-Side WordPress Analytics

Use WP Statistics or similar plugins that track visits via PHP on the server side.

  • No JavaScript, no browser dependency
  • Less feature-rich than GA4
  • Completely immune to CSP, ad blockers, and WAF rules

⚠️ Why This Will Happen Again

ModSecurity rule sets update monthly. Each update can re-introduce false positives. If you rely on client-side analytics on shared hosting, keep this guide bookmarked — you may need it again after the next rule update. The .htaccess override in Step 4 is durable, but host-managed automation (like Newfold's Htaccess Manager) could overwrite it during updates.

Quick Reference: The Diagnostic Flowchart

GA4 shows zero data?

  1. Is the GA4 tag in page source? → If NO: tag installation issue
  2. Are there CSP errors in browser console? → If NO: different issue (check consent mode, measurement ID)
  3. Is a CSP header in response headers? → If NO: check if tag is loading but data isn't sending
  4. Is CSP in .htaccess? → If YES: remove it from .htaccess
  5. Is CSP from a plugin? (deactivate security plugins) → If YES: reconfigure that plugin
  6. Is CSP from Cloudflare? (check Transform Rules) → If YES: modify in Cloudflare dashboard
  7. Is CSP still present after eliminating all of the above? → It's ModSecurity. Contact your host.

🛠️ Need Help Diagnosing This?

We offer website security audits that include WAF configuration review, header analysis, and analytics verification. If your GA4 isn't tracking and you've exhausted standard troubleshooting, we can identify the exact cause and work with your host to resolve it.

Learn About Our Website Security Audit →