RoastMyOpsec

Safety

CSP style-src vs unsafe-inline for Public Sites

March 28, 2023

CSP style-src vs unsafe-inline for public sites is how you allow first-party CSS without inviting injected style tags. style-src lists which stylesheets and inline style blocks may apply. 'unsafe-inline' lets any inline CSS run, which is how a markup injection becomes a defacement or a data-exfil via attribute tricks — still not a substitute for script-src. Nonces or hashes for styles work like they do for scripts. Host allowlists still run every file on that origin. Most brochure sites keep unsafe-inline because a CMS injects style attributes; Report-Only is how you find that honestly. RoastMyOpsec reads CSP quality on the landing HTML. It does not score missing style-src as a standalone F, does not inject CSS, and does not exploit style sinks.

The practical difference

script-src is JavaScript. style-src is CSS. object-src is plugins. A tight script-src with style-src 'unsafe-inline' is a common CMS stall. style-src-elem and style-src-attr split elements versus attributes if you need that precision.

Hashes pin exact inline blocks. Nonces need a fresh value per HTML response — do not bake a nonce into a year-old static file. See nonces vs hashes for scripts; the same failure modes apply to CSS.

How to choose style-src

Static marketing site with hashed CSS files: style-src 'self' plus SRI on those links, no unsafe-inline. SSR: nonce on style tags you emit. Tag managers and CSS-in-JS that require inline: Report-Only until you can nonce, and still enforce frame-ancestors. Do not set style-src * or https:.

TechniqueWhat it allowsFailure modeTakeaway
style-src 'self'Same-origin stylesheetsInline attributes still blockedDefault for hashed CSS files
Nonce or hashMarked or exact inline CSSStale nonce on cached HTMLBetter than unsafe-inline
'unsafe-inline'Any inline styleInjected CSS runsCMS stall; Report-Only first
script-src noncePage JavaScriptDoes not cover CSSSet both directives

When style-src wins

style-src wins when script-src looks strict and the CMS still dumps style attributes. Trusted Types wins for DOM XSS sinks, not for CSS. Neither replaces SRI on third-party stylesheets.

What the roast can prove

CSP presence and quality signals on the HTML response can surface. Missing style-src is not scored as its own finding. Confirm the directive in the header. Pair with SRI if styles load from a CDN.

Common mistakes

The first mistake is copying script-src into style-src including 'unsafe-eval'.

The second mistake is style-src https: because one font host kept moving.

The third mistake is treating 'unsafe-inline' on styles as harmless because XSS is a script problem.

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 cover inline CSS?
No. Set style-src. unsafe-inline on scripts and styles are separate holes.
Should brochure sites allow unsafe-inline styles?
Prefer not. If a CMS forces it, stay in Report-Only for styles and still enforce framing.
Does RoastMyOpsec score style-src?
It grades CSP quality overall. It does not inject CSS or treat style-src as the only CSP check.

Sources

Related guides