We deployed a stricter Content-Security-Policy on the ASH marketing site in early June. The goal was operational: tighten the visitor privacy surface, eliminate any inline script execution that could compromise the visitor’s browsing context. The CSP was carefully reviewed, tested against staging, and rolled out to production on a Tuesday morning.
By Tuesday afternoon, the site’s email obfuscation features were broken. Email addresses that had been displayed as obfuscated forms (info[at]anonymousserverhosting[dot]com) were now showing raw email patterns to scrapers. Our visitor browsers were also throwing CSP violation reports.
The cause: Cloudflare’s Email Obfuscation feature, enabled in our Cloudflare dashboard settings, injects inline JavaScript into served pages to obfuscate email addresses against simple scrapers. The injected script violated our new CSP. The CSP enforcement blocked the script. The obfuscation feature stopped working.
This post is the four-hour investigation, the operational lessons, and what we changed about our deployment process for CSP and similar visitor-facing security policies.
What we were trying to accomplish
The ASH marketing site is served from a static Astro build behind Cloudflare. The visitor privacy posture matters operationally because our customer base values privacy infrastructure. A marketing site that loaks visitor data through third-party scripts or compromises visitor browsing security would contradict the brand positioning.
The CSP we deployed was intended to:
Block all third-party script execution. Only scripts served from our own origin should run.
Block inline scripts. Even on our own origin, scripts should be served from explicit files rather than inline in HTML, providing better protection against XSS scenarios.
Block style violations similarly. Inline styles allowed only with nonce-based validation.
Block all third-party connections. The browser should not make any connection to external origins from our pages, eliminating tracking and analytics exposure.
The full CSP was:
Content-Security-Policy: default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
base-uri 'self';
form-action 'self';
object-src 'none';
upgrade-insecure-requests;
We had tested this against the staging environment over several days. The site behaved normally. No browser console errors. No broken features. Confidence was high for the production rollout.
What broke
On Tuesday morning, the CSP went to production. The site continued loading normally for the visitor experience. The visible pages rendered. The navigation worked. Links functioned. The PageSpeed score stayed at 97.
The issues emerged in two distinct ways throughout Tuesday.
Issue 1: Email obfuscation visibly failed
The contact page and other pages with email addresses started displaying raw email forms to some visitors. Our contact email was being shown as support@anonymousserverhosting.com in plain text where previously it had been obfuscated.
The obfuscation depended on a Cloudflare-injected script that replaced obfuscated patterns in the page with mailto links containing real email addresses. Without the script running, the obfuscated patterns remained but the JavaScript-driven enhancement that normally produced clickable mailto links did not happen.
The visible failure was that scrapers could now see the raw obfuscated pattern (which is partially obfuscated but more readable than the JavaScript-protected form). The email harvesting protection was degraded.
Issue 2: CSP violation reports flooded our log
The CSP was configured with a report-uri pointing to our endpoint. Tuesday morning began receiving CSP violation reports at rate higher than baseline. By Tuesday afternoon we had over 10,000 reports, all matching a single pattern: blocked inline script from Cloudflare’s domain.
The reports were the alerting signal. The pattern was consistent enough that we identified Cloudflare as the source within minutes of looking at the reports.
The four-hour diagnostic
The investigation took longer than the fix because the cause was non-obvious.
Hour 1: Identifying that something was wrong
The CSP violation report flood was the first visible symptom. We started investigating around 11:30 AM. Initial hypothesis: a customer-side script (analytics, embedded widget) was violating CSP from a customer-facing page.
Reviewed the violation reports more carefully. The pattern was consistent: inline script blocked, originating URL was our own domain (not customer pages), script content was related to email patterns.
Hour 2: Local testing
We tried to reproduce locally. Built the site from source, served from a local web server, applied the same CSP. No violations.
This was confusing. The site was identical between local and production. The CSP was identical. Yet violations only appeared in production.
The difference must be something between the build output and the visitor’s browser. The CDN was the obvious candidate. We started investigating Cloudflare-specific behaviors.
Hour 3: Cloudflare investigation
We reviewed Cloudflare’s documentation on script injection. Several Cloudflare features inject scripts:
- Email Obfuscation
- Rocket Loader
- Apps & Integrations (some)
- Cloudflare Insights / Analytics
We had Email Obfuscation enabled. We did not have Rocket Loader enabled. We did not have third-party Apps enabled. We had Insights enabled but tested separately.
The Email Obfuscation feature was the most likely candidate. We checked the Cloudflare dashboard, confirmed the feature was enabled, found the documentation explaining what it does.
Hour 4: Confirmation and remediation
We disabled Email Obfuscation in Cloudflare. Within minutes, the CSP violation reports stopped. The visible email obfuscation was now genuinely missing (the feature was off) but no CSP violations.
The diagnosis was confirmed. The fix was to either re-enable the feature with CSP nonce support or accept the trade-off of running without Cloudflare’s automated obfuscation.
The trade-off we considered
The decision was between two imperfect options.
Option A: Keep CSP strict, lose Cloudflare email obfuscation
The strict CSP serves our visitor privacy goals. Cloudflare’s email obfuscation is helpful but not essential. We can implement our own JavaScript-free email obfuscation using HTML entity encoding (info@example.com) that does not require any script execution.
Option B: Relax CSP to allow Cloudflare’s inline script
The Cloudflare obfuscation works automatically. The CSP relaxation (script-src 'self' 'unsafe-inline') reintroduces inline script execution capability. This weakens the XSS protection meaningfully because any attacker who could inject inline script content would have its execution permitted.
We chose Option A. The visitor privacy posture matters more than the convenience of automatic email obfuscation. We implemented HTML entity encoding for all email addresses on the site. The obfuscation is less sophisticated than Cloudflare’s JavaScript-based approach but works without requiring any script execution.
The trade-off is documented in our security operations documentation. Future infrastructure changes should know that Cloudflare obfuscation cannot be used with our CSP.
The procedural lessons
The incident produced procedural improvements.
Staging needs to mirror Cloudflare configuration
Our staging environment was served directly from the origin server without Cloudflare in the path. The CSP testing on staging did not include the Cloudflare modifications that production receives. The mismatch was the structural cause of the production surprise.
We updated the staging environment to use Cloudflare for serving (with the same Cloudflare features enabled as production). The CSP testing now includes the Cloudflare layer behavior. Issues like the Email Obfuscation conflict surface in staging rather than production.
Cloudflare feature audit for CSP-relevant features
The Cloudflare dashboard has many features that inject scripts or modify served content. Most are off by default but accumulate over time as different team members enable them for specific purposes.
We did an audit of all enabled Cloudflare features for CSP relevance. Several features were enabled that we did not need and that would have caused CSP issues. We disabled the unnecessary ones. The remaining features are documented with their CSP implications.
CSP report-uri monitoring before strict enforcement
The CSP report-uri was configured but we did not actively monitor it before the strict CSP rollout. We could have caught the issue in report-only mode if we had been watching.
We added active monitoring for CSP violation reports with alerts on patterns above baseline. The monitoring catches policy violations earlier and provides diagnostic data before any visible impact.
Two-week shadow period before strict enforcement
For future CSP changes, we now run report-only mode for two weeks before enforcing. The report-only mode produces CSP violation reports without blocking the violations. We can see what would have been blocked before actually blocking.
The two-week shadow period catches issues that staging testing might miss. The period is long enough to surface intermittent issues, longer-tail browsers and edge cases.
Cloudflare configuration version control
Cloudflare configuration was not in version control. Changes to Cloudflare settings were applied through the dashboard and not tracked. Some configuration had been changed by team members weeks before the CSP rollout without documentation.
We moved Cloudflare configuration to Terraform-managed infrastructure-as-code where feasible. Some settings still require dashboard configuration but the bulk is now version-controlled.
Customer-facing communication
The visible impact on visitors was limited (the email obfuscation regression affected scrapers more than legitimate visitors). We did not need to communicate to customers about the incident.
The internal team communication was the operational improvement. Team members who use Cloudflare for other ASH brands now know about the Email Obfuscation/CSP interaction.
What we learned about Cloudflare specifically
The investigation produced useful knowledge about Cloudflare’s behavior beyond the immediate incident.
Cloudflare’s Email Obfuscation works by parsing served HTML, identifying email patterns, replacing them with obfuscated placeholders, and injecting JavaScript that restores the real emails for legitimate browsers.
The injected JavaScript runs inline rather than as an external script. This conflicts with strict CSP that disallows inline scripts.
Cloudflare does support CSP nonces for some features but Email Obfuscation specifically does not (as of June 2025). The feature is essentially incompatible with strict CSP.
Rocket Loader (Cloudflare’s JavaScript optimization feature) has similar CSP conflicts but with a different remediation path.
Cloudflare Insights / Analytics has CSP-compatible deployment options but the default configuration may not be CSP-compatible.
Customers with strict CSP requirements should audit Cloudflare features for CSP compatibility during initial Cloudflare setup rather than discovering issues during CSP deployment.
What we changed in our production environment
After the incident:
CSP strict policy remains in production. The policy serves the visitor privacy goals.
Cloudflare Email Obfuscation is disabled. Email obfuscation now happens through HTML entity encoding in the source HTML.
Cloudflare Insights is configured in CSP-compatible mode.
Other Cloudflare features (caching, security rules) continue operating without modification.
Cloudflare configuration is partially in Terraform with the remainder documented in our security operations documentation.
CSP violation reporting is actively monitored with alerts above baseline.
What other operators should consider
For other operators with similar setups, several considerations:
Test CSP in environments that mirror production CDN/proxy configuration. Local or staging testing without the CDN layer misses CDN-specific behaviors.
Audit CDN features that modify served content. Email obfuscation, script optimization, analytics injection, security features all may modify HTML in ways that conflict with strict policies.
Run CSP report-only mode before enforcement. The reports surface issues that testing might miss.
Document CDN-related trade-offs explicitly. Trade-offs between CDN convenience features and security policy are real and need explicit decision.
Monitor CSP violations actively. The monitoring provides early warning for issues introduced by upstream changes (CDN updates, browser updates, library updates).
Version control CDN configuration where possible. Configuration drift in CDN settings produces hard-to-debug issues when something changes that affected team members are not aware of.
The bigger principle
The incident illustrates a broader pattern in infrastructure operations. The boundary between “your application” and “your infrastructure providers” is often less clean than it appears. CDN behaviors, hosting provider configurations, third-party services all modify the operational reality in ways that may not be obvious during development.
The discipline that helps: explicit awareness of where modifications happen, what they do, and how they interact with policies you set. Treating the CDN as transparent infrastructure that “just delivers what you build” produces surprises like this one. Treating the CDN as an active participant in the served content produces better operational outcomes.
For our operational practice, the incident reinforced existing discipline rather than producing new discipline. The procedural improvements are refinements rather than fundamental changes. The four hours of investigation produced documentation and process improvements that will save more hours over future operations.
The customer-facing brand impact was zero. Visitors saw the site work normally throughout. The internal operational learning was the value. The post-mortem documentation supports current and future team members understanding the operational considerations.
For operators reading this with strict CSP plans: the Cloudflare Email Obfuscation conflict is one specific instance of a general class of CDN-CSP interactions. Audit your specific configuration. Test with the actual production stack. Watch the violation reports during rollout. The work to do this well is bounded; the cost of not doing it is bounded incidents like the one we had.
Three minutes to fix. Four hours to diagnose. Several hours of documentation and process improvement. Total operational cost: about half a day. The work to prevent the next similar incident: hours of documentation and audit. The investment is worthwhile; the lesson is documented; the next CSP-style rollout will benefit from this experience.