CSS Tutorial 0/203 lessons ~6 min read Lesson 154

    Content Security Policy

    content security policy content security policy for css controls which stylesheets load, whether inline styles execute, and from which origins

    Course progress0%
    Focus
    27 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Content Security Policy for CSS controls which stylesheets load, whether inline styles execute, and from which origins url() may fetch — closing XSS gaps when HTML sanitization fails. Staff engineers align style-src with nonce/hash strategies and audit third-party widget CSS.

    Business problem

    Injected style tags and inline style attributes bypass script-src-only CSP — attackers exfil data or restyle login forms. style-src 'unsafe-inline' negates much of CSP value for CSS-heavy SPAs.

    • Compliance: PCI and SOC2 expect CSP on payment pages.
    • Third-party: Analytics widgets demand inline styles — policy tension.

    Why this feature exists

    CSP Level 3 style-src governs <link rel=stylesheet>, <style> blocks, and style="" attributes. Nonce and hash allowlist specific inline; 'unsafe-inline' ignored when nonce present in modern browsers.

    • style-src-elem vs style-src-attr: Split control of elements vs attributes (CSP3).
    • report-only: Rollout without breaking prod.

    Browser rendering perspective

    Browser enforces CSP before applying CSS — blocked stylesheet logged to console and report-uri. Inline critical CSS needs nonce on style tag matching header.

    • Violation reports: JSON POST to report-uri/report-to endpoint.

    Internal browser workflow

    CSP rollout: Inventory all CSS sources (bundles, CDN, inline critical, third-party) → report-only 2 weeks → tighten style-src → add nonces to SSR inline styles → block style attributes or use style-src-attr 'none'.

    Feature deep dive

    CSP headers for CSS:

    css
    Content-Security-Policy:
    default-src 'self';
    style-src 'self' 'nonce-{RANDOM}';
    style-src-attr 'none';
    report-uri /csp-report;
    <!-- SSR -->
    <style nonce="{RANDOM}">/* critical CSS */</style>
    <link rel="stylesheet" href="/app.css">

    Syntax

    Meta tag limited — prefer HTTP header:

    css
    <meta http-equiv="Content-Security-Policy"
    content="style-src 'self' 'nonce-abc123'">

    Examples

    Next.js middleware nonce: Generate per-request nonce; pass to styled-components or emotion if configured; inline style attributes blocked via style-src-attr 'none' forcing classes.

    Real-world use

    GitHub, Stripe Checkout, and Google publish strict CSP. report-uri monitoring teams detect injection attempts. Hash-based CSP for static inline critical CSS on marketing sites.

    Real production example

    Edge nonce injection at CDN for HTML document; static CSS from 'self'; block user style=; weekly CSP report review dashboard.

    • Hash: sha256-base64 for immutable inline critical CSS chunk if nonce impractical on static CDN.

    Enterprise use case

    CSP central team maintains policy templates per app tier — marketing relaxed vs checkout strict.

    Accessibility considerations

    style-src-attr 'none' blocks inline style on elements — ensure all styling via classes; AT not affected if HTML semantics intact.

    Performance considerations

    Per-request nonces prevent HTML caching at CDN — edge nonce generation or hash for static critical CSS tradeoff.

    SEO considerations

    CSP violations don't directly affect SEO — but blocked CSS hurts render — monitor accidental over-blocking.

    Scalability considerations

    Micro-frontends merge CSP at shell — union of style-src origins or single bundle host.

    Common production issues

    Incidents: Deployed style-src 'self' without new CDN domain — site unstyled 2 hours. Third-party chat widget broke — emergency hash allowlist.

    Debugging guide

    DevTools Console CSP violation messages name blocked URI. report-only mode collects without user impact.

    Best practices

    • Deploy style-src via HTTP header not meta when possible.
    • Use nonces for inline critical CSS; avoid unsafe-inline.
    • Set style-src-attr 'none' if product can ban inline styles.
    • Start report-only; monitor before enforce.
    • Document third-party CSS origins in inventory.

    Anti-patterns

    • style-src * or unsafe-inline on checkout.
    • Ignoring CSP reports after launch.
    • Same nonce reused across users/sessions predictably.

    Trade-offs

    • Benefit: Blocks injected style XSS when encoding fails.
    • Cost: Nonce hurts HTML cache; third-party friction.

    Architecture review questions

    • style-src excludes unsafe-inline on sensitive pages?
    • Inline critical CSS uses nonce or hash?
    • CSP reports monitored?

    Interview questions

    How do you CSP-protect CSS in SSR app?(Advanced)

    Per-request nonce in header and inline style tags; style-src 'self' nonce-{n}; style-src-attr 'none'; external bundles from self or SRI CDN; report-only first; hash fallback for static marketing pages.

    Follow-up: styled-components with CSP?

    Hands-on exercise

    Exercise: Add CSP report-only with style-src 'self'; fix violations; switch to enforce; verify injected style blocked.

    Staff engineer notes

    • CSP is layered defense — encoding still primary.

    Common pitfalls

    • Forgetting CDN domain in style-src after migration.

    Try it yourself

    Edit the CSS panel — the preview updates live. Use DevTools Performance and Accessibility panels to validate.

    Try it yourself

    Preview

    Summary

    Content Security Policy for CSS uses style-src, style-src-attr, nonces, and hashes to block injected stylesheets and inline style XSS — rolled out via report-only monitoring with third-party origin inventory.

    Key takeaways

    • style-src and style-src-attr control CSS injection surface.
    • Use nonces/hashes instead of unsafe-inline.
    • Roll out report-only and monitor violations.
    Ready to mark this lesson complete?Track your journey across the entire course.