A script policy declares unsafe-inline without a nonce, hash or strict-dynamic

In the reportCSP allows 'unsafe-inline' scripts without nonce or hash

csp_unsafe_inline_effective · Issue

Short answer

This security advice appears when one captured Content Security Policy lists 'unsafe-inline' for scripts and the same directive has no nonce, hash or 'strict-dynamic'. That token can permit inline scripts under this policy; another enforcing policy may still block them. Give needed inline scripts a nonce or hash, or move them into files.

Severity: Notice. Security advice in Good to know. Review the captured inline-script allowance; another enforcing policy may still restrict execution, and this check makes no ranking claim.

Why it matters

web.dev's guide to a strict policy recommends nonces or hashes for scripts and notes that recent browsers ignore 'unsafe-inline' when one is present. Without those protections in this directive, the token may permit inline script under this policy; other enforcing policies can still restrict it.

What to do

  1. Look at the finding: it shows the policy, the script directive we judged and up to ten pages that send it.
  2. Give your inline scripts a nonce or a hash listed in the policy, or move them into files.
  3. Then remove 'unsafe-inline' from the script directive, or keep it only beside the nonce or hash, where recent browsers ignore it.

What we read

We read the enforcing policies of each crawled page with our own user agent: each policy in a Content-Security-Policy response header, and a CSP <meta> tag inside <head>. Report-only headers are not read. Each policy is judged on its own, as it is written, not combined with the page's other policies the way a browser applies them.

In a policy we take script-src, or default-src when there is no script-src. The policy is reported when that directive contains 'unsafe-inline' and, in the same directive, no 'strict-dynamic', no nonce and no sha256, sha384 or sha512 hash. script-src-elem and script-src-attr are not read.

Pages that send the same policy text are reported together, one finding per exact text; a policy that carries a new nonce on every response gives each page a finding of its own. Pages whose headers or HTML were not captured in full are not judged.

Example & evidence

Illustrative example — one policy, not a live audit.

https://bakery.example/ and the other pages send:

Content-Security-Policy: script-src 'self' 'unsafe-inline'; object-src 'none'

script-src allows 'unsafe-inline' and has no nonce, hash or 'strict-dynamic', so the policy is reported with the pages that send it.

Content-Security-Policy: script-src 'nonce-r4nd0m' 'unsafe-inline' 'strict-dynamic'; object-src 'none'; base-uri 'none'

A possible correction: with a nonce in script-src, recent browsers ignore 'unsafe-inline', and the check no longer reports the policy.

Confirm & check again

Check for yourself: open the page's response headers and read script-src in Content-Security-Policy, or default-src if there is no script-src: 'unsafe-inline' with no 'nonce-…', 'sha256-…' or 'strict-dynamic' beside it is what the check reports.

Check again: Full audit — run a new full audit. With complete coverage, this policy-text finding closes only when no currently crawled page sends the same flagged policy text; a new page using the old text keeps it open. Adding a nonce or hash changes the text and the new policy is judged afresh. A page that stops sending any policy loses that policy text; the separate missing-policy check is currently deferred, so this does not establish adequate protection.

Limits & sources

Each policy is judged alone: a second enforcing policy that blocks inline scripts does not clear the finding, although a browser applies both, and script-src-elem or script-src-attr are ignored. The check does not see whether inline scripts exist or run, or whether a nonce or hash matches them.

Confidence: High because the policy text is read directly.

Sources

Editorial review: 2 November 2026