unsafe-inline (Google Research). This guide shows how to set up a strict, nonce-based CSP, which mistakes to avoid, and how automated security header monitoring ensures your policy remains effective over time.What a Content Security Policy Is and Why It Matters
A Content Security Policy is an HTTP response header that tells the browser which resources a page is allowed to load. This includes scripts, stylesheets, images, fonts, frames, form targets, and connections to external servers. The browser blocks everything that is not explicitly permitted — including injected scripts that an attacker has smuggled in through an XSS vulnerability.
The reasons why CSP remains so underused despite its effectiveness are manifold: the configuration is complex, mistakes break websites, and many developers underestimate the risk. That said, adoption has been steadily increasing — from 15% in 2022 to 19% in 2024 to 21.9% in 2025 (HTTP Archive). At the same time, 97.3% of all websites already use HTTPS (HTTP Archive), showing that the industry takes transport security seriously — but application security via CSP still lags significantly behind.
The gap between HTTPS adoption and CSP deployment has a simple explanation: HTTPS can be set up with a single certificate and a server configuration. CSP, on the other hand, requires a precise understanding of all resources loaded on a website and their origins. Every external script, every embedded widget, and every API connection must be explicitly allowed. This effort deters many website operators — even though a strict CSP blocks the vast majority of XSS attacks: according to Google, only about 25% of XSS bugs remain exploitable even under a strict CSP — the remaining three quarters are reliably blocked (Google web.dev).
Essential CSP Directives at a Glance
A CSP consists of one or more directives, each governing a resource type. Each directive defines which sources the browser may load that resource from. The correct combination determines whether your CSP actually protects or merely simulates security.
| Directive | Controls | Recommended Value |
|---|---|---|
| default-src | Fallback for all resource types | 'self' |
| script-src | JavaScript sources | 'nonce-{random}' 'strict-dynamic' |
| style-src | CSS sources | 'self' 'nonce-{random}' |
| img-src | Images | 'self' data: https: |
| font-src | Fonts | 'self' |
| connect-src | XHR, Fetch, WebSocket | 'self' https://api.your-domain.com |
| frame-src | Embedded frames | 'none' (or explicit domains) |
| frame-ancestors | Who may embed your page | 'self' |
| form-action | Form targets | 'self' |
| base-uri | Base URL for relative paths | 'self' |
| upgrade-insecure-requests | Upgrade HTTP resources to HTTPS | (no value needed) |
Many configurations only set default-src 'self' and consider their CSP complete. However: script-src, style-src, and other directives do inherit from default-src, but once you set a specific directive, the fallback is overridden. Check each directive individually — or use automated header monitoring that detects gaps in your header configuration.
Why Most CSP Implementations Fail
The numbers are sobering: 91% of websites with CSP use the unsafe-inline directive (HTTP Archive Web Almanac 2024), 78% use unsafe-eval (HTTP Archive Web Almanac 2024), and 95% of all whitelist-based CSPs can be bypassed (Google Research). Only 2% of all analyzed websites have a CSP rated as effective (Bitsight). These numbers show: the biggest problem is not the absence of CSP, but its misconfiguration.
Allows execution of arbitrary inline scripts, completely negating XSS protection. 91% of CSPs affected (HTTP Archive Web Almanac 2024).
Allows eval(), setTimeout('string'), and new Function(). Opens the door for code injection. 78% of CSPs affected (HTTP Archive Web Almanac 2024).
Domains like .googleapis.com or .cloudflare.com allow thousands of subdomains — including those attackers can abuse as JSONP endpoints.
Without frame-ancestors, form-action, or base-uri, critical attack vectors like clickjacking and phishing remain open.
Nonce-Based CSP: The Recommended Approach
Google Research has shown in a comprehensive study that whitelist-based CSPs are bypassable in 95% of cases because at least one domain on the whitelist contains an exploitable endpoint (Google Research). The solution: nonce-based policies. Each legitimate script receives a random, one-time token (nonce) that is regenerated with every page load. Only scripts with the correct nonce execute — injected scripts do not know the token and are blocked.
Despite this clear recommendation, only 20% of websites with CSP use a nonce-based policy (HTTP Archive Web Almanac 2024). This means: even among websites that have implemented CSP, around 80% use an outdated or insecure approach.
Content-Security-Policy:
default-src 'self';
script-src 'nonce-{SERVER_GENERATED_RANDOM}' 'strict-dynamic';
style-src 'self' 'nonce-{SERVER_GENERATED_RANDOM}';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.your-domain.com;
frame-ancestors 'self';
form-action 'self';
base-uri 'self';
upgrade-insecure-requests;The 'strict-dynamic' directive allows scripts authorized via nonce to load additional scripts — even without their own nonce. This greatly simplifies integration of tag managers and third-party libraries without compromising security. Browsers that do not support strict-dynamic ignore it and fall back to the whitelist.
Beyond nonces, CSP Level 3 offers additional mechanisms for a robust policy. The 'strict-dynamic' mode combined with nonces ensures that dynamically loaded scripts — such as those injected by bundlers or module loaders — are correctly authorized without each script needing its own nonce. The newer report-to directive replaces the older report-uri and uses the browser's Reporting API to send violations in a structured format to an endpoint. This enables more granular analysis: you see not only which resource was blocked, but also the document URL, the violated directive, and the blocked URI in a machine-readable JSON format.
Rolling Out CSP: From Report-Only to Enforcement
The biggest fear when deploying CSP: Will it break my website? This fear is justified — a misconfigured CSP blocks legitimate resources and can disrupt functionality. That is why a phased rollout is recommended, where you first observe and then tighten.
- Inventory: Identify all external resources your website loads — scripts, stylesheets, fonts, images, iFrames, API connections. A security scan provides a complete overview.
- Report-Only mode: Start with
Content-Security-Policy-Report-Onlyinstead ofContent-Security-Policy. The browser reports violations but blocks nothing. This shows you which resources would be affected. - Set up report endpoint: Configure
report-urior the newerReporting APIso violations are sent to an endpoint. This lets you detect issues early. - Iterate on the policy: Analyze reports, add allowed sources for legitimate resources, and remove unnecessary entries.
- Activate enforcement: Once no unexpected violations have appeared for 2–4 weeks, switch from Report-Only to the enforcing
Content-Security-Policyheader. - Ongoing monitoring: CSP is not a one-time configuration. New scripts, changed third-party domains, or CMS updates can break your policy. Automated header monitoring detects changes immediately.
CSP for Common CMS and Frameworks
The practical implementation of CSP depends heavily on your tech stack. WordPress, Shopware, and static websites require different approaches. What they all have in common: the CSP header should ideally be set at the web server level (nginx/Apache), not in application code — this prevents an application-level attack from also disabling the CSP.
WordPress
WordPress websites face a particular challenge: the Gutenberg editor and many plugins make extensive use of inline scripts and eval(). A strict CSP therefore requires nonce support through a dedicated security plugin or a custom integration in functions.php. Alternatively, you can set the CSP header in the nginx or Apache configuration and gradually eliminate inline scripts. Monitor success with regular security scans that verify the CSP still holds after plugin updates.
Shopware and E-Commerce
E-commerce platforms typically load payment provider scripts, tracking pixels, and chat widgets — each of these external resources must be accounted for in the CSP. Particularly critical: payment iFrames require correct frame-src entries, and the connect-src directive must allow API calls to payment providers. An overly restrictive CSP can disrupt the checkout process — so be sure to test changes in a staging environment and monitor the login flow and checkout after rollout.
Regardless of the system in use: never test CSP changes directly in production. Use a staging instance and Report-Only mode to validate the impact on all critical functions — especially checkout, contact forms, and embedded content — before rollout. Automated monitoring immediately detects when the Report-Only header reports violations that indicate misconfigurations.
Static Websites and SPAs
For static websites and Single Page Applications (SPAs), CSP configuration is comparatively straightforward because you have full control over all loaded resources. Set the header directly in the web server configuration, replace inline scripts with external files, and use 'strict-dynamic' for dynamically loaded modules.
CSP and Other Security Headers: Working Together
CSP is just one building block of a comprehensive HTTP security header setup. For maximum protection, CSP works alongside other headers that complement each other. An isolated CSP header is better than none, but only the combination closes the most common attack vectors.
- Strict-Transport-Security (HSTS): Enforces HTTPS and prevents protocol downgrade attacks. Complements the CSP directive
upgrade-insecure-requests. - X-Content-Type-Options: Prevents MIME type sniffing — an attack vector where the browser interprets a resource differently than intended.
- X-Frame-Options: Prevents clickjacking by embedding your page in a frame. Overlaps with the CSP directive
frame-ancestorsbut is recommended as a fallback for older browsers. - Referrer-Policy: Controls what information is shared in the referrer URL when navigating to external sites.
- Permissions-Policy: Restricts access to browser APIs like camera, microphone, geolocation, and payment.
If you have already optimized your SSL configuration, adding security headers is the logical next step. Together, transport security (HTTPS/HSTS) and application security (CSP, Permissions-Policy) form a multi-layered security concept that makes attackers' work significantly harder.
XSS Attacks and Their Economic Impact
XSS is not a theoretical threat. Injection vulnerabilities rank at position 5 in the OWASP Top 10:2025 (OWASP) — a category encompassing XSS, SQL injection, and command injection. The average cost of a data breach is USD 4.88 million (IBM 2024), with web application attacks being one of the most common initial vectors.
For German SMBs, the consequences can be existential: a successful XSS attack can exfiltrate customer data, triggering a reporting obligation under Art. 33 GDPR. Add potential fines, reputational damage, and revenue losses during remediation. A strictly configured CSP blocks the vast majority of XSS attacks according to Google — only about 25% of XSS bugs remain exploitable under it (Google web.dev) — an enormous security gain for relatively low configuration effort.
While the average cost of a data breach is USD 4.88 million (IBM 2024), a strict CSP requires only a one-time configuration plus ongoing monitoring. The return on investment is rarely as clear-cut in IT security as with Content Security Policies.
CSP Monitoring: Detect Violations, Maintain Your Policy
A CSP is not a set-and-forget header. Websites change constantly: new scripts are added, third parties change their domains, CMS updates introduce new inline scripts. Without continuous monitoring, you only notice changes when features break or security gaps emerge.
There are two monitoring layers: CSP violation reports via the report-uri directive provide real-time data on blocked resources. Regular header checks ensure that the CSP header is still in place, contains the right directives, and that no insecure fallbacks like unsafe-inline have been added.
The XICTRAQ security scan checks your HTTP response headers for completeness and configuration errors with every check. If your CSP header disappears, an unsafe-inline directive is added, or a directive is missing, you receive an immediate notification — via email, Slack, Discord, or Telegram.
CSP Checklist for Production
default-src 'self'as baseline — blocks everything not explicitly allowedscript-srcwith nonce instead of whitelists — 95% of whitelist CSPs are bypassable (Google Research)- Avoid
unsafe-inlineandunsafe-eval—unsafe-inlineappears in 91%,unsafe-evalin 78% of all CSPs and is the main reason for ineffectiveness (HTTP Archive Web Almanac 2024) - Set
frame-ancestors 'self'— protects against clickjacking - Set
form-action 'self'— prevents form data from being sent to attacker domains - Set
base-uri 'self'— blocks base-tag injection, an often overlooked attack vector - Add
upgrade-insecure-requests— forces HTTPS for all subresources - Configure report endpoint — without violation reports, problems fly under the radar
- Test regularly — after every CMS update, plugin change, or deployment, verify with automated monitoring
Common Pitfalls During CSP Migration
The most common problems during CSP deployment are predictable and avoidable. Knowing them saves you weeks of debugging and production outages.
HTML attributes like onclick, onload, or onerror do not work under a strict CSP. Migrate event handlers to external JavaScript files or use addEventListener().
Chat widgets, analytics pixels, and A/B testing tools often load additional scripts. 'strict-dynamic' solves this elegantly. Alternatively, cookieless tracking works without external scripts.
Frameworks that inject styles at runtime require either a nonce for style-src or a configuration that generates external CSS files.
When a CDN provider changes their domains or you switch CDNs, your CSP breaks. Automated monitoring detects such changes before your visitors notice.
CSP in the Context of Compliance and Standards
CSP is increasingly becoming a compliance topic. The OWASP Top 10:2025 lists injection vulnerabilities at position 5 (OWASP), and CSP is recommended as the primary countermeasure against XSS. For organizations that must comply with PCI DSS, an effective CSP is now practically mandatory. The German BSI IT-Grundschutz also recommends configuring security headers as part of web server hardening.
Furthermore, a CSP can contribute to GDPR compliance: if a CSP prevents injected scripts from exfiltrating customer data, it significantly reduces the risk of a reportable data breach. In combination with a solid website security checklist and regular security audits, CSP forms the technical foundation for demonstrable protective measures.
Validate Your CSP Header and Secure Your Configuration
Only 2% of websites have a CSP rated as secure according to a recent analysis (Bitsight). This is not because CSP is too complex — but because the initial configuration is frequently not validated and not continuously maintained. After a CMS update, plugin change, or deployment modification, a previously secure CSP can suddenly develop gaps.
Automated monitoring solves this problem. The XICTRAQ security scan regularly checks your HTTP security headers and immediately detects if a CSP directive is missing, an insecure source has been added, or the entire header has disappeared. In combination with API monitoring and backup heartbeats, this creates a seamless monitoring chain for your entire infrastructure.
This article is based on data from: HTTP Archive Web Almanac 2024 and 2025 (CSP directive analysis), Google Research (CSP bypass study), Google web.dev (strict CSP effectiveness), HackerOne/Bugcrowd (vulnerability reports), Bitsight (header analysis), OWASP Top 10:2025, IBM Cost of a Data Breach 2024.
Frequently Asked Questions About Content Security Policy
Can a CSP break my website?
Content-Security-Policy-Report-Only header, analyze violations, adjust the policy, and only switch to enforcement mode after a testing period. Automated monitoring helps detect problems early.Is CSP sufficient as the sole XSS protection?
How does CSP affect website performance?
Do I need to configure CSP separately for each page?
How can I tell if my current CSP is effective?
unsafe-inline, unsafe-eval, or overly broad whitelists. In our experience, an automated security scan that checks your headers against best practices and provides specific improvement suggestions is the most reliable approach.