WSTG - Latest
Testing for Content Security Policy
| ID |
|---|
| WSTG-CONF-12 |
Summary
Content Security Policy (CSP) is a declarative allow-list policy enforced through Content-Security-Policy response header or equivalent <meta> element. It allows developers to restrict the sources from which resources such as JavaScript, CSS, images, files etc. are loaded. CSP is an effective defense in depth technique to mitigate the risk of vulnerabilities such as Cross Site Scripting (XSS) and Clickjacking.
Content Security Policy supports directives which allow granular control to the flow of policies. (See References for further details.)
Test Objectives
- Review the Content-Security-Policy header or meta element to identify misconfigurations.
How to Test
Testing for Content Security Policy (CSP) weaknesses requires more than verifying the presence of the header. The tester should evaluate whether the policy meaningfully reduces the attack surface and is properly enforced.
Identify and Confirm CSP Enforcement
- Inspect HTTP responses for the presence of the
Content-Security-Policyheader. - Check for
Content-Security-Policy-Report-Only. If only Report-Only is present, the policy is not enforced. - Verify whether CSP is delivered via HTTP header or
<meta>tag (HTTP headers are preferred). - Note that CSP delivered via
<meta>tags does not support certain directives such asframe-ancestors,report-uri,report-to, orsandbox. - Confirm that the policy is consistently applied across sensitive endpoints.
Review High-Risk Directives
Inspect the policy for insecure or overly permissive directives:
unsafe-inlineallows inline scripts or styles and significantly weakens XSS protections.unsafe-evalpermits dynamic code evaluation (eval()), increasing bypass risk.unsafe-hashesmay allow inline execution if hashes are predictable or improperly scoped.- Wildcard (
*) sources may allow loading resources from any origin.- Partial wildcards such as
https://*or*.cdn.comshould be carefully evaluated. - Determine whether allowlisted domains host JSONP endpoints or user-controlled content.
- Partial wildcards such as
- Absence or misuse of
frame-ancestorsmay expose the application to clickjacking. - Missing
object-src,base-uri, or restrictivedefault-srcdirectives may weaken policy effectiveness. - Review usage of
require-trusted-types-forandtrusted-types. In high-risk applications, absence of Trusted Types may leave DOM-based injection sinks exposed. Iftrusted-typespolicies are defined, ensure they are not overly permissive. - Check for duplicate directives or conflicting policy definitions that may result in unintended enforcement behavior.
Validate Nonce and strict-dynamic Usage
If the policy uses nonces:
- Confirm that nonces are cryptographically random.
- Verify that nonces are regenerated per response and not reused.
- Ensure that legacy inline script patterns are not inadvertently trusted.
If strict-dynamic is used:
- Understand that trust propagates from nonce- or hash-based scripts.
- Confirm that no unsafe trust chain allows attacker-controlled script loading.
Evaluate CSP Reporting Mechanisms
If report-uri or report-to is configured:
- Verify that reporting endpoints are reachable and functional.
- Determine whether sensitive information is exposed in reports.
- Confirm that reporting does not create new injection or denial-of-service vectors.
Attempt Controlled Bypass Techniques
Where appropriate and authorized, attempt to validate enforcement by testing controlled payloads:
- Inline script injection attempts.
- Data URL–based payloads.
- JSONP callback manipulation from allowlisted domains.
- DOM-based gadget chaining using trusted script sources.
Successful execution of injected JavaScript indicates CSP misconfiguration or ineffective enforcement.
Assess Policy Strength
Business-critical applications should aim to implement a strict policy. A robust CSP typically:
- Avoids
unsafe-inlineandunsafe-eval. - Uses nonce- or hash-based script controls.
- Restricts object embedding (
object-src 'none'). - Restricts base tag manipulation (
base-uri 'none'). - Restricts framing using
frame-ancestors.
Common CSP Bypass Patterns
Even when CSP is present, misconfigurations or design weaknesses may allow bypass. Testers should consider the following common patterns:
JSONP and Trusted Third-Party Endpoints
If a CSP allowlists third-party domains (e.g., CDNs), determine whether those domains expose JSONP endpoints or user-controlled content. Attackers may leverage callback injection to execute arbitrary JavaScript while still complying with the policy.
Wildcard and Broad Source Policies
Policies that rely on wildcards (*, https://*, *.example.com) significantly expand the trust boundary. Subdomain takeovers or compromised third-party services may enable bypass within the allowed scope.
Nonce Reuse or Predictable Nonces
If nonces are reused across requests or generated predictably, attackers may reuse or guess them to execute injected scripts. Each response should generate a fresh, cryptographically strong nonce.
Over-Reliance on strict-dynamic
While strict-dynamic improves nonce-based policies, trust propagates from trusted scripts. If a trusted script loads attacker-controlled resources, the protection may be weakened.
Missing Defense-in-Depth Directives
Absence of directives such as:
object-src 'none'base-uri 'none'frame-ancestors
may leave the application exposed to object injection, base tag manipulation, or clickjacking, even if script execution is partially restricted.
CSP in Report-Only Mode
Applications sometimes deploy CSP in Report-Only mode indefinitely. In such cases, violations are logged but not blocked, providing no real protection.
Remediation
Organizations should implement a strong, well-scoped Content Security Policy that meaningfully reduces the attack surface rather than simply satisfying compliance requirements.
General Recommendations
- Avoid use of
unsafe-inlineandunsafe-eval. - Prefer nonce- or hash-based script controls.
- Use a restrictive
default-srcdirective. - Explicitly define:
object-src 'none'base-uri 'none'frame-ancestors
- Minimize the number of allowlisted third-party domains.
- Regularly review CSP policies when introducing new frontend dependencies.
Deployment Best Practices
- Deploy
Content-Security-Policy-Report-Onlytemporarily for testing, then enforceContent-Security-Policyonce validated. - Monitor violation reports for legitimate breakage and potential attack attempts.
- Prefer
report-to(CSP Level 3) while maintainingreport-urifor backward compatibility where required. - Ensure nonces are cryptographically random and regenerated per response.
- Review policies during major frontend refactoring or framework changes.
Strict Policy Guidance
A strict policy provides protection against stored, reflected, and certain DOM-based XSS attacks and should be the goal for high-risk or business-critical applications.
Based on nonce-based approaches, example policies include:
Moderate Strict Policy:
script-src 'nonce-r4nd0m' 'strict-dynamic';
object-src 'none';
base-uri 'none';
Locked Down Strict Policy:
script-src 'nonce-r4nd0m';
object-src 'none';
base-uri 'none';
Note: 'nonce-r4nd0m' is shown as an example placeholder. In practice, nonces must be cryptographically strong, base64-encoded values that are uniquely generated for every HTTP response.
Teams should adapt strict policies carefully, ensuring compatibility with application architecture while maintaining security objectives.
Tools
- Google CSP Evaluator
- CSP Auditor - Burp Suite Extension
- CSP Generator Chrome / Firefox
- CSP Validator
- OWASP ZAP – Includes automated and passive analysis for CSP misconfigurations.
- CSPBypass – Tool designed to help security testers analyze and attempt bypass techniques against restrictive CSP implementations.