# 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](#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-Policy` header.
- 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 as `frame-ancestors`, `report-uri`, `report-to`, or `sandbox`.
- Confirm that the policy is consistently applied across sensitive endpoints.

### Review High-Risk Directives

Inspect the policy for insecure or overly permissive directives:

- `unsafe-inline` allows inline scripts or styles and significantly weakens XSS protections.
- `unsafe-eval` permits dynamic code evaluation (`eval()`), increasing bypass risk.
- `unsafe-hashes` may 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.com` should be carefully evaluated.
    - Determine whether allowlisted domains host JSONP endpoints or user-controlled content.
- Absence or misuse of `frame-ancestors` may expose the application to clickjacking.
- Missing `object-src`, `base-uri`, or restrictive `default-src` directives may weaken policy effectiveness.
- Review usage of `require-trusted-types-for` and `trusted-types`. In high-risk applications, absence of Trusted Types may leave DOM-based injection sinks exposed. If `trusted-types` policies 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-inline` and `unsafe-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-inline` and `unsafe-eval`.
- Prefer nonce- or hash-based script controls.
- Use a restrictive `default-src` directive.
- 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-Only` temporarily for testing, then enforce `Content-Security-Policy` once validated.
- Monitor violation reports for legitimate breakage and potential attack attempts.
- Prefer `report-to` (CSP Level 3) while maintaining `report-uri` for backward compatibility where required.
- Ensure nonces are cryptographically random and regenerated per response.
- Review policies during major fronte