# How to test Content Security Policy changes

> Content Security Policy testing confirms that a page loads approved resources and the browser blocks the rest. Learn how to test directives, nonces, and report-only rollout on agent-written web changes, and how Factory security review and Automated QA check them.

URL: https://factory.com/articles/content-security-policy-testing-coding-agents
Published: 2026-09-29
Updated: 2026-10-23

To test a Content Security Policy change, load the changed route in a real browser, confirm the new resource loads under the smallest directive that fits, and prove that a resource from an unapproved host is blocked. Inspect every CSP header the browser receives, check that nonces change per response, and keep the evidence with the pull request.

A coding agent may add an analytics script, embedded frame, worker, or inline style that conflicts with the current policy. Broadening a directive until the page renders can remove protection from unrelated routes.

[Content Security Policy Level 3](https://www.w3.org/TR/CSP3/) defines directives that control resource loading and other browser behavior. A useful test suite checks the effective browser policy, including headers from the application, proxy, and content delivery network.

## Start from the existing policy

Capture the policy for representative routes before changing it. Record each directive, its source list, and whether the header enforces or only reports violations. A report-only policy produces useful observations but does not block a resource.

Identify the smallest directive affected by the feature. Adding a domain to `default-src` can grant access to several resource types that lack a more specific directive. The table pairs common feature changes with the directive that usually owns them.

| Feature change | Directive to edit |
| --- | --- |
| New image or avatar host | `img-src` |
| Embedded third-party application | `frame-src` |
| New script or tag manager | `script-src` |
| API or analytics endpoint | `connect-src` |
| Hosted web font | `font-src` |
| Web or service worker | `worker-src` |

Keep development behavior separate. Hot reload, source maps, and local tooling often need allowances that production pages should not inherit.

## Test allowed and blocked browser behavior

Load a page that exercises the changed feature and inspect console violations and network requests. Confirm that approved scripts, styles, images, connections, frames, fonts, and workers behave as expected. Then attempt a controlled resource from a host that the policy should reject.

Inline scripts need focused coverage. If the application uses nonces, confirm that each response creates an unpredictable value, applies it only to intended elements, and sends the matching value in the policy. A static nonce reused across responses defeats its purpose.

Test error and authentication routes too. Framework fallbacks or proxy-generated pages can carry a different header from the main application. Multiple CSP headers combine as additional restrictions, so inspect every header the browser receives rather than only application configuration.

## Bound the agent's CSP work and review the evidence

Specify the route, resource type, approved host, and current policy owner. Require a focused diff and browser evidence for both the intended resource and a blocked control. Reject blanket wildcards or unsafe inline execution unless an existing, documented policy explicitly requires them.

The task should preserve deployment headers outside its scope. A page-level fix must not silently change a global reverse-proxy policy.

Capture the final response headers, tested route, browser console result, and blocked-control outcome. Redact tokens and avoid saving authenticated response bodies. A clean console alone is insufficient because the test may not exercise the new resource.

Deploy report-only changes with a defined observation period when the application needs telemetry before enforcement. Review the reports for affected routes, remove obsolete allowances, then rerun the enforcing browser test. Repeat this check after proxy or content delivery configuration changes, even when application code stays unchanged.

## How Factory checks CSP changes

Factory is a platform for running a software factory, where agents called Droids take work from a signal to a reviewed pull request. For a policy change, Factory checks the diff at review time and the running page in a browser.

The flow below shows how the two checks meet on the pull request.

Pull request</span><br/><span style='color:#8A8380 !important'>CSP or resource change</span>"]
    B["<span style='color:#FAFAFA !important;font-weight:600'>Security review</span><br/><span style='color:#8A8380 !important'>candidates, then validation</span>"]
    C["<span style='color:#FAFAFA !important;font-weight:600'>Automated QA</span><br/><span style='color:#8A8380 !important'>real browser on the changed route</span>"]
    D["<span style='color:#FAFAFA !important;font-weight:600'>Evidence</span><br/><span style='color:#8A8380 !important'>headers, console, blocked control</span>"]
    E["<span style='color:#FAFAFA !important;font-weight:600'>Repository owner</span><br/><span style='color:#8A8380 !important'>reviews and merges</span>"]
    A --> B --> D
    A --> C --> D
    D --> E
`}
/>

**Security review on the diff.** Factory's [security review](https://docs.factory.com/software-factory/security-review) runs in two passes. The first finds candidate vulnerabilities, and the second re-checks each one before it is reported with a severity from P0 (critical) to P3 (low). A `security-review-guidelines` skill in `.factory/skills/` can add repository rules, such as rejecting new wildcards in `script-src` or new `unsafe-inline` allowances.

**Browser evidence.** Factory's [Automated QA](https://docs.factory.com/software-factory/automated-qa) generates a project QA skill with `/install-qa`. For web apps it uses agent-browser, which drives a real browser and captures screenshots, so the changed route can be loaded and the result attached to the pull request.

**Command boundaries.** Factory's [permission rules](https://docs.factory.com/autonomy-and-safety/permission-rules) can allow, require approval for, or block shell commands. Restrict local server and browser test commands to the known project workflow.

To set up these checks on your own repository, run these commands in the Droid CLI.

<div className="not-prose my-6 flex flex-col gap-3 [&_button]:!w-auto">
  <div className="grid grid-cols-1 gap-y-5 md:grid-cols-[max-content_1fr] md:gap-x-4">
    
    <span className="text-base-300 text-sm leading-relaxed"><strong className="text-light-base-primary font-medium">One-time setup.</strong> Generates a QA skill that tests the flows each pull request touches.</span>
    
    <span className="text-base-300 text-sm leading-relaxed"><strong className="text-light-base-primary font-medium">One-time setup.</strong> Adds automated code and security review to your pull requests.</span>
  </div>
</div>

## Frequently asked questions

### What is Content Security Policy testing?

Content Security Policy testing checks whether a page loads its intended resources while the browser blocks unapproved ones. It inspects the effective policy the browser receives, including headers from the application, proxy, and content delivery network.

### Why not add a new host to default-src?

A domain added to default-src can grant access to several resource types that lack a more specific directive. Put the host in the smallest directive the feature needs, such as img-src for an image host or frame-src for an embedded application.

### How do you test CSP nonces?

Confirm that each response creates an unpredictable nonce, applies it only to intended elements, and sends the matching value in the policy. A static nonce reused across responses defeats its purpose.

### What does a report-only CSP do?

A report-only policy records violations but does not block resources. Run it for a defined observation period, review the reports for affected routes, remove obsolete allowances, and then rerun the enforcing browser test.

### How does Factory check CSP changes?

Factory security review runs on pull requests in two passes and reports validated findings with P0 to P3 severity. A security-review-guidelines skill can add rules such as rejecting wildcards, and Automated QA can drive a real browser against the changed route.

## Further reading

- [CORS checks for agent-generated web services](https://factory.com/articles/cors-testing-agent-generated-services)
- [How to test file upload security in agent code](https://factory.com/articles/file-upload-security-testing-coding-agents)
- [Session cookie testing with coding agents](https://factory.com/articles/session-cookie-testing-coding-agents)
- [Security review docs](https://docs.factory.com/software-factory/security-review)
