Docs

Issue guide · Security

Content Security Policy has loopholes

SeverityLow
CategorySecurity
ScopeWhole site
EffortMedium
Verified bySecurity scan (weekly, or Re-scan)
Rule keysec_csp_weak

Short answer

Your Content Security Policy allows scripts in a way an attacker can use: 'unsafe-inline' without a nonce or hash, 'unsafe-eval', a wildcard *, a bare https:, http: or data: source, or no script-src/default-src at all. Any of these lets most injected scripts run, so the policy gives little XSS protection. Replace them with nonces or hashes, ideally combined with 'strict-dynamic'.

Why it matters

With 'unsafe-inline', an injected <script> tag or onerror= attribute runs as if there were no policy; a wildcard or bare https: lets an attacker load a script from any server they control; 'unsafe-eval' turns injected strings into code. Google's analysis of real-world policies found that most allowlist-based CSPs could be bypassed, which is why nonce- or hash-based policies are now recommended. Security headers do not affect rankings; this is about whether the policy you already maintain actually protects visitors.

How Glimana detects it

Glimana reads the Content-Security-Policy header of your HTTPS home page (or, when there is no header, a CSP meta tag) and evaluates the directive that governs scripts: script-src, or default-src when script-src is absent. It fails with low severity if neither directive exists, if 'unsafe-inline' appears without a nonce, a hash or 'strict-dynamic', if 'unsafe-eval' appears, or if the list contains *, https:, http:, an http:// host or data:. When 'strict-dynamic' is present, host and scheme entries are ignored, as CSP Level 3 browsers do. A missing object-src 'none' or base-uri is shown as a suggestion but does not fail the check, and style-src is not judged. With no CSP at all, this check is Not applicable.

How to fix it

Watch out

A nonce must be random and new on every response. If a full-page cache (a caching plugin, a CDN that caches HTML, Varnish) stores the page, every visitor receives the same nonce and the protection is gone; use hashes for static inline scripts, or keep pages with nonces out of the cache. Removing 'unsafe-eval' can break older libraries and some tag-manager setups, so test in report-only mode first.

  1. Find the finding in Glimana. Open Security; this check is in the Security headers group, with the evidence from the last scan under its title. The same problem is listed under Issues › Content Security Policy has loopholes.
  2. Apply the fix on your platform.

    Generate a fresh random nonce for every response (at least 128 bits, base64-encoded), put it on every script tag you output, <script nonce="R4nd0mV4lu3">, and send the matching header: Content-Security-Policy: script-src 'nonce-R4nd0mV4lu3' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none'. Browsers that support nonces ignore 'unsafe-inline' and https: in this policy; they are only fallbacks for very old browsers, and Glimana evaluates the policy the same way. Move inline handlers such as onclick= into scripts with addEventListener, because nonces do not cover them.

    In WordPress 6.4 and later, scripts printed through the core script API go through wp_get_script_tag() and wp_get_inline_script_tag(), so the wp_script_attributes and wp_inline_script_attributes filters can add a nonce attribute to them. Generate the nonce once per request (for example base64_encode(random_bytes(16))) in a small plugin and send the matching header from the send_headers hook. Scripts that a theme or plugin echoes directly bypass these filters, so run the policy in report-only mode and check the console before enforcing it.

    A static header set by a Transform Rule cannot carry per-request nonces. For inline scripts that never change, use hashes instead: script-src 'self' 'sha256-…', copying the hash from the browser console message that names the blocked script. Nonces at the edge need a Cloudflare Worker that rewrites both the HTML and the header on every response.

  3. Check it in Glimana. Press Re-scan on the Security page (up to two scans an hour) or wait for the weekly scan on Sunday; the problem closes when the check passes.

How the fix is verified

Press Re-scan on the Security page (or wait for the weekly Sunday scan); the problem closes when the check passes.

Sources

Was this page helpful?

Last updated 2026-11-07 · Contact support