RoastMyOpsec

Safety

CSP script-src-elem vs script-src for Public Sites

March 11, 2023

CSP script-src-elem vs script-src for public sites is a split allowlist versus the combined one. script-src-elem governs <script> elements (src and inline script blocks). script-src-attr governs event-handler attributes like onclick. script-src is the shorthand that fills both when you omit the split directives, and it can still feed worker-src fallback. A tight script-src-elem does not lock inline handlers. unsafe-inline on script-src still weakens both. RoastMyOpsec grades CSP quality overall. It does not score missing script-src-elem as a standalone F, does not compare nonces to every tag, and does not exploit XSS.

The practical difference

Use script-src if you want one list for tags and handlers. Split into script-src-elem and script-src-attr when you can nonce or hash tags but still need to kill inline handlers. worker-src is workers, not <script>. default-src is the floor if you name neither.

GTM and CMS themes that inject onclick= need the attr half, not a looser elem half.

How to choose a script policy

Brochure with a nonce'd loader: script-src 'nonce-...' 'strict-dynamic' (or hashes) and no unsafe-inline. Need to allow CDN <script src> but forbid onclick: script-src-elem with hosts/nonces, script-src-attr 'none'. Report-Only first. See nonces vs hashes and default-src vs named directives.

DirectiveWhat it allowsDoes not coverTakeaway
script-srcTags and handlers (shorthand)A split you did not setUsual brochure start
script-src-elem<script> elementsonclick= and friendsPin tags; lock attrs separately
script-src-attrEvent-handler attributes<script src>Prefer 'none'
worker-srcWorker scriptsPage <script>See worker-src vs script-src

When the split still wins

script-src-elem wins when tags can be nonce'd but leftover HTML handlers cannot. script-src still wins as one list for a simple brochure. Missing the split is not a finding if script-src is already tight. Pair with style-src vs unsafe-inline if the CMS also inlines CSS.

What the roast can prove

CSP quality signals on the landing header can surface. Missing script-src-elem is not scored as its own finding. Confirm which half actually applies. Pair with Report-Only until enforcing will not break the theme.

Common mistakes

The first mistake is script-src-elem 'self' with script-src still 'unsafe-inline'.

The second mistake is treating script-src-elem as coverage for onclick=.

The third mistake is splitting directives and forgetting worker-src.

Free audit the URL you own

RoastMyOpsec is a defensive public-surface roast: headers, cookies, sensitive paths, and more — no exploit payloads. Start with the free audit, then open the vault if the blurred findings look expensive.

Free audit now

FAQ

Does script-src-elem replace script-src?
No. It only covers <script> elements. Handlers are script-src-attr. The shorthand script-src fills both if you omit the split.
Should brochure sites set script-src-elem?
Only if you need a different allowlist than handlers. A tight script-src is enough. Missing the split is not a roast F.
Does RoastMyOpsec score script-src-elem?
No. It grades CSP quality overall and does not treat script-src-elem as the only script check.

Sources

Related guides