In one paragraph
A missing Content-Security-Policy header means the response does not declare an enforced browser policy for permitted scripts and other resources. It does not prove the page has an XSS vulnerability, but it removes an important defence if injection occurs. Fix it by testing a policy in report-only mode, resolving legitimate violations, and then enabling enforcement on your HTML responses.
Why it matters
Content Security Policy, or CSP, restricts what a document may load or execute. A carefully configured policy can prevent injected scripts from running even when an application has an output-encoding or sanitisation defect. It supplements secure coding; it does not replace it.
Without an enforced policy, the browser does not apply CSP restrictions supplied through that response header. That is different from saying every possible injected script will execute: exploitability still depends on the injection context, application behaviour, and other browser protections.
How WebAuditOS evaluates this finding
According to the supplied check specification, a missing or empty enforcing header fails. A policy that does not restrict scripts, allows a wildcard for the relevant script sources, or permits unsafe inline scripts without a nonce or hash receives a warning. A Report-Only header does not satisfy the enforcing-header requirement.
The check uses script-src-elem, script-src, or default-src as appropriate to its script-source analysis. It considers multiple enforced policies together when assessing the described weaknesses. This is a targeted check, not a complete CSP security review: broad scheme sources and other policy weaknesses can remain even when the check passes.
How to fix it
- Identify the layer that serves the final HTML response. Configure CSP in your application, reverse proxy, hosting configuration, or CDN. Avoid accidentally adding conflicting policies in several layers.
- Inventory legitimate resources on each page type. Include login, checkout, embedded media, analytics, support tools, and account screens. A homepage-only test is insufficient.
- Deploy a report-only candidate. The following is an illustrative script-hardening policy, not a production-ready configuration for every site:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'nonce-REPLACE_PER_RESPONSE'; object-src 'none'; base-uri 'self'; report-uri /csp-report
Implement the reporting endpoint before relying on it. report-uri is deprecated but remains useful for compatibility; modern reporting uses report-to with a configured Reporting-Endpoints header.
- Generate an unpredictable nonce for each response and put the matching nonce attribute only on trusted script elements. Never deploy the placeholder as a literal value. For static, cacheable pages, consider build-generated hashes instead.
- Refactor inline event handlers into addEventListener calls. A nonce on a script element does not authorise an onclick attribute. Add explicit resource directives only for dependencies you actually need.
- Exercise complete user journeys and review violations. Once legitimate functionality works under the candidate policy, serve it as Content-Security-Policy. Keep monitoring after enforcement.
Verify the fix in browser DevTools: inspect the final document response in Network, confirm the enforcing header, and check the Console for blocked resources. Rescan the affected URLs in WebAuditOS. Test policy strength separately rather than treating a green finding as proof that XSS is impossible.
What the fix can break
Enforcement can block inline scripts, external loaders, fonts, API connections, frames, or styles that the policy does not authorise. The visible symptom may be a broken checkout button rather than an HTTP error.
Nonce handling must match your caching architecture. Reusing a nonce in a shared cached HTML response undermines its intended per-response unpredictability. Use a suitable dynamic delivery design or a hash-based policy for static output.
Do not resolve every violation by adding a wildcard, unsafe-inline, or unsafe-eval. Those changes can restore functionality while discarding much of the protection you intended to add.
Questions
Does a missing CSP header mean the website has been hacked?
No. The finding identifies a missing browser security control, not a confirmed compromise or a demonstrated XSS exploit. Investigate injection risks separately.
Does Content-Security-Policy-Report-Only fix this finding?
No. Report-only mode records violations without enforcing the policy. It is a deployment stage, not equivalent visitor protection.
Can I use a meta tag instead of a response header?
Browsers support a limited enforcing CSP in a meta element, but not every directive or reporting feature. The supplied WebAuditOS check reads response headers, so a meta-only policy does not satisfy it.
What should I check next?
Review the related security-headers guide at /guides/security-headers and the HSTS finding at /checks/security/strict-transport-security-header-missing. CSP and HSTS address different risks; one does not substitute for the other.