Enterprise AI CSP Validator

Analyze live policies, detect vulnerabilities, and optimize wildcard bundling instantly.

Target URL

Agent: Googlebot Proxy

The Standard for Edge Policy Optimization

Wildcard Bundling

Large CSP headers can bloat your HTTP response, negatively impacting Time to First Byte (TTFB). The AI engine detects redundant domains (e.g., api.app.com, cdn.app.com) and recommends safe wildcard bundling like *.app.com to compress header size without compromising zero-trust boundaries.

Server-Aware Baselines

If an upstream server returns no Content-Security-Policy or Content-Security-Policy-Report-Only header, the tool analyzes your Server and X-Powered-By headers to generate a custom, strict baseline policy specifically architected for your tech stack.

Frequently Asked Questions

What is a Content Security Policy (CSP) and why does every website need one?

A Content Security Policy is an HTTP response header that instructs the browser to only load resources — scripts, styles, images, fonts, frames — from explicitly approved sources. Without a CSP, a successful Cross-Site Scripting (XSS) attack can inject and execute arbitrary JavaScript in a visitor's browser, stealing session cookies, redirecting users to phishing pages, or silently exfiltrating form data. CSP is the last line of browser-enforced defense after your application code has been compromised. Since 2023, Google's Lighthouse security audit flags missing CSP headers, and major compliance frameworks including PCI-DSS v4.0 and SOC 2 now require documented script execution controls — which CSP directly satisfies.

What is a CSP score and how is it calculated?

This tool calculates a deterministic security score from 1 to 100 based on ten 2026 compliance checks. Each check carries a weighted deduction if failed: missing unsafe-inline protection in script-src deducts 30 points (the highest penalty, as it fully negates XSS protection); missing object-src 'none' deducts 20 points; missing frame-ancestors deducts 15 points; missing base-uri restriction deducts 10 points; missing unsafe-eval protection deducts 10 points; absent nonces or strict-dynamic deducts 8 points; missing upgrade-insecure-requests deducts 5 points; unrestricted form-action deducts 5 points; absent require-trusted-types-for deducts 5 points; and missing violation reporting deducts 2 points. Scores of 90–100 are green, 70–89 yellow, 50–69 orange, and below 50 red. Unlike letter-grade systems, a numeric score makes incremental improvements visible and gives developers a clear priority order for remediation.

What is the difference between script-src 'unsafe-inline' and style-src 'unsafe-inline'?

script-src 'unsafe-inline' permits inline <script> tags and JavaScript event handlers like onclick="" to execute — this is a critical XSS vulnerability because an attacker who injects any HTML into your page can immediately run JavaScript. style-src 'unsafe-inline' permits inline <style> tags and style="" attributes — this enables CSS injection attacks (used for data exfiltration via attribute selectors) but does not directly allow JavaScript execution. This tool's compliance engine evaluates them independently: the Inline Scripts Blocked check inspects script-src only and will correctly pass a policy that blocks inline scripts even if inline styles are permitted. Many CSP scanners incorrectly fail both checks together, producing false positives on policies that are actually safe for script execution.

Why is unsafe-inline in script-src flagged as a severe vulnerability?

The 'unsafe-inline' keyword in script-src or default-src permits any inline <script> block, inline event handler (onload, onclick, onerror), and javascript: URI to execute in the browser. This single directive completely disables the XSS protection that CSP provides — a browser with this policy set will execute injected scripts just as freely as if no CSP existed at all. The correct replacement is cryptographic nonces ('nonce-abc123') generated fresh on every server response, or SHA hashes ('sha256-...') of specific trusted inline blocks. Both allow only pre-approved inline code to run while blocking anything injected by an attacker.

What is strict-dynamic and when should I use it?

'strict-dynamic' in script-src allows a trusted nonce-validated script to dynamically load additional scripts at runtime without those child scripts needing to be individually whitelisted. This is essential for modern JavaScript bundlers, tag managers, and single-page application frameworks that load modules programmatically. Without strict-dynamic, developers must whitelist every CDN hostname their scripts load from — which is both operationally fragile and potentially insecure if a whitelisted CDN is compromised. With strict-dynamic, only the root script needs a trusted nonce; all scripts it loads inherit that trust. Note that strict-dynamic ignores 'unsafe-inline' and host allowlists in supporting browsers (Chrome 52+, Firefox 52+, Safari 15.4+), making policies that combine it with nonces extremely robust.

What does frame-ancestors 'none' do and why is it required for anti-clickjacking?

The frame-ancestors directive controls which origins are permitted to embed your page inside a <frame>, <iframe>, <embed>, or <object>. Setting it to 'none' prevents any origin from framing your page, which blocks clickjacking attacks — where an attacker renders your page in a transparent iframe layered over a decoy UI to trick users into clicking buttons they cannot see. frame-ancestors is the modern CSP-native replacement for the legacy X-Frame-Options header, and unlike X-Frame-Options, it supports multiple origins and is not subject to the same parsing inconsistencies across older browsers. If your application uses legitimate iframes (embedded checkout, embedded dashboards), use frame-ancestors 'self' https://trusted-partner.com instead.

Why does this tool evaluate object-src as a standalone check rather than relying on default-src?

object-src controls loading of Flash, Java applets, and other browser plugins via <object>, <embed>, and <applet> tags. Although Flash is end-of-life, the <object> tag can still be exploited to load arbitrary content on some browsers. More critically, if object-src is not explicitly set to 'none', it inherits from default-src — and a permissive default-src silently opens plugin injection as an attack surface. This tool enforces that object-src 'none' must be declared explicitly in the policy, not inferred. The Google CSP Evaluator and OWASP CSP Cheat Sheet both require this explicit declaration for a policy to be considered robust.

Why do generic CSP scanners get blocked by Cloudflare, Akamai, or AWS WAF?

Enterprise Web Application Firewalls fingerprint HTTP requests by User-Agent, TLS cipher order, HTTP/2 settings frames, and behavioral patterns. Standard HTTP client libraries (Python requests, Node axios, Go http) produce signatures that WAFs identify as automated scanners and return a 403, a CAPTCHA challenge page, or a JavaScript challenge — none of which contain the real CSP headers from the origin server. This tool fetches URLs from Cloudflare's edge network using a Googlebot/2.1 User-Agent, which most WAFs explicitly whitelist to preserve SEO crawlability. The Advanced Options panel also allows injecting arbitrary custom headers — including Authorization, CF-Access-Client-Id, or staging environment bypass tokens — to retrieve CSP headers from access-controlled pre-production endpoints.

What happens when a scanned site has no Content Security Policy header?

If neither Content-Security-Policy nor Content-Security-Policy-Report-Only is present in the server response, the tool switches to baseline generation mode. It reads the Server header (e.g., nginx/1.27.0, Apache/2.4.62) and X-Powered-By header (e.g., Express, PHP/8.3) to infer the server stack, then generates a strict, production-ready baseline CSP tailored to that infrastructure. The generated policy uses object-src 'none', base-uri 'self', frame-ancestors 'none', upgrade-insecure-requests, and restricts all fetch directives to 'self' as a starting point. It is designed to score 80+ out of 100 immediately and be incrementally widened as you add third-party services.

What is require-trusted-types-for 'script' and why is it a 2026 compliance requirement?

Trusted Types is a browser API (supported in Chrome 83+, Edge 83+, and partially in Firefox via polyfill) that prevents DOM-based XSS by requiring that strings passed to dangerous DOM sinks — innerHTML, document.write(), eval(), setTimeout(string) — must first be processed through a registered Trusted Types policy. The CSP directive require-trusted-types-for 'script' enforces this at the browser level: any attempt to assign a raw string to a dangerous sink throws a TypeError and is logged as a CSP violation. This stops entire classes of DOM XSS that nonce-based CSP cannot address (because nonces protect script loading, not script manipulation of existing DOM). Google's internal security team mandates Trusted Types for all new Google web applications, and it is now included in the 2026 OWASP Top 10 Proactive Controls.

What is upgrade-insecure-requests and does it replace HSTS?

upgrade-insecure-requests instructs the browser to automatically upgrade all HTTP resource requests from the page to HTTPS before fetching them — including images, stylesheets, scripts, and XHR calls. This prevents mixed-content warnings and passive network eavesdropping on insecure subresource loads. It is not a replacement for HTTP Strict Transport Security (HSTS): HSTS prevents the browser from making any HTTP connection to your domain at all (enforced via a preload list), while upgrade-insecure-requests only upgrades subresource loads within a single page response. Both should be deployed together. Note that upgrade-insecure-requests does not upgrade the navigation request itself — a user typing http:// in their browser still requires HSTS to redirect to HTTPS.

What is the base-uri directive and what attack does it prevent?

The base-uri directive restricts which URLs can be used in a page's <base> tag. Without this restriction, an attacker who can inject HTML into your page can insert <base href="https://attacker.com/">, which causes all relative URLs on the page to resolve against the attacker's domain — silently redirecting script loads, form actions, and navigation to a malicious server. Setting base-uri 'self' limits the base URL to your own origin. Setting it to 'none' disables the <base> tag entirely. This directive is not inherited from default-src, so it must be declared explicitly. Base URI injection is a particularly dangerous attack vector on pages that use relative paths for script loading.

How does CSP violation reporting work and how do I set it up?

CSP violation reporting sends a JSON payload to a designated endpoint every time the browser blocks a resource that violates the policy. There are two directives: the legacy report-uri /csp-endpoint (supported everywhere but deprecated) and the modern report-to directive (which references a Reporting-Endpoints response header). Reports include the blocked URI, the violated directive, the document URL, and the source file and line number — making them invaluable for identifying policy mistakes before they affect users and detecting active injection attacks in production. Free reporting endpoints include report-uri.com and uriports.com. The recommended deployment strategy is to first deploy Content-Security-Policy-Report-Only with a reporting endpoint for 2–4 weeks to collect violations without blocking anything, then promote to enforcing Content-Security-Policy once the policy is tuned.

What is the difference between Content-Security-Policy and Content-Security-Policy-Report-Only?

Content-Security-Policy is the enforcing header — the browser blocks any resource that violates it and optionally reports the violation. Content-Security-Policy-Report-Only is the audit header — the browser reports violations but does not block anything. Report-Only mode is the standard way to deploy a new or tightened policy in production without risking breakage: run it for several weeks, review violation reports to identify legitimate resources being flagged, add those resources to the policy, and once violations drop to zero (or near zero), switch to the enforcing header. Both headers can be sent simultaneously — the enforcing policy controls what is blocked, while the Report-Only header lets you test a stricter future policy in parallel.

Why does a high CSP score not guarantee complete XSS protection?

A high CSP score means the policy is well-structured and follows current best practices, but CSP is a mitigation layer, not a complete XSS prevention system. Several attack vectors remain outside CSP's scope: DOM-based XSS via innerHTML assignments in allowed scripts (requires Trusted Types to address); JSONP endpoints on whitelisted domains that can be abused as script injection vectors; browser extension interference; and policy bypass via strict-dynamic misconfigurations. CSP should always be layered with input validation and output encoding at the application level, Subresource Integrity (SRI) for third-party scripts, and regular dependency auditing. Think of a 95/100 CSP score as meaning your browser-level defense is maximally configured — your application code still needs to be secure.