How to fix Inline Scripts Present?

inline-scripts-present page

The issue

Inline <script> blocks keep a site from enforcing a Content Security Policy that blocks injected code. The browser can’t tell an inline script you wrote from one an attacker injected, so allowing every inline script allows theirs too.

The cause is that the policy can only allow inline scripts all at once, with 'unsafe-inline', or one by one, with a nonce or hash. A page full of inline scripts with neither pushes the policy toward 'unsafe-inline'.

Scope

Inline scripts are in each page’s HTML: templates, framework hydration data, analytics snippets and tags added by third-party scripts. Each source of markup has to be checked.

How to check you have it

  • In probeo: the policy side is reported as csp:script-src-unsafe-inline, graded major, when the policy lets inline scripts run without a nonce or hash.
  • By hand: in page source, find each <script> that has code between its tags and no src. type="application/ld+json" and other data blocks aren’t executed and don’t count.
  • In the browser: with a policy that doesn’t allow 'unsafe-inline', each blocked inline script is reported in the console.

The fix

Move inline scripts into files, or give each one that must stay inline a nonce or a hash.

A nonce is a random value the server generates for each response and puts both in the policy and on each trusted <script>. A hash allows one exact script and suits pages that are cached. Configuration can move into a <script type="application/json"> block that a script file reads. Then remove 'unsafe-inline' from script-src.

Done when: every executable inline script is gone or carries a valid nonce or hash, the policy doesn’t allow 'unsafe-inline', and the check above comes back clean.

Do not

  • Do not keep 'unsafe-inline' as the permanent answer.
  • Do not forget inline event handlers, which count as inline script too.
  • Do not use a fixed or predictable nonce.
  • Do not allow inline scripts in areas that hold user-supplied content.

FAQ

Why are inline scripts considered less secure than external scripts?

They aren’t less safe in themselves. The difference is that the policy can allow an external script by where it comes from, while an inline script has no origin to check, so it needs a nonce, a hash or a blanket allowance.

What about inline scripts for configuration or initialization?

Put the data in a <script type="application/json"> block or data- attributes, and read it from a script file. Data blocks aren’t executed, so the policy doesn’t need to allow them.

How do CSP nonces work with inline scripts?

The server generates a random, unguessable value for each response. It appears in script-src as 'nonce-…' and in the nonce attribute of each trusted script. The browser runs only inline scripts whose value matches.

Should all inline scripts be converted simultaneously?

No. Start where injected content is most likely, such as pages that render user input, then the templates you control, then third-party snippets.

Do inline styles have the same security implications?

Less severe ones. CSS can’t run JavaScript, but injected styles can still alter a page or leak data through URLs it loads. style-src controls them separately; scripts come first.

Can frameworks like React generate inline scripts?

Yes, mostly for server-rendered state passed to the client. Most frameworks can add a nonce to these, or put the state in a JSON data block.

Which product detects this

Probeo checks this on every page of your site as part of Site Clarity. This page explains one instance; the product tells you every page that has it.