Advanced

Locking what the page may load

I escaped the text but a script still loaded from a CDN. A Content Security Policy says which sources the browser may run, so escaping is not the whole gate.

What you will see

inline style with nonce-abc123 passes, forged inline without nonce is blocked

About 1 min of reading

Try It

Send a CSP and confirm a remote script is blocked.

1

A page with script-src 'self' refuses a script from another origin.

curl -sI https://yoursite/ | grep -i content-security-policy

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Content-Security-Policy: script-src 'self'; style-src 'self' 'nonce-abc123'
2

The inline style you wrote carries the nonce, so it passes; a forged one does not.

print('inline style with nonce-abc123 passes, forged inline without nonce is blocked')

Before you run it, say out loud what it will print. Then open the answer.

What it prints
inline style with nonce-abc123 passes, forged inline without nonce is blocked
Do not add 'unsafe-inline' to silence a CSP violation. That flag re-allows exactly the inline code CSP was meant to block. Use the nonce for the inline blocks you genuinely need.

Data Flow

The CSP header whitelists sources per type; inline blocks pass only with a per-response random nonce, and frame denial closes clickjacking.
1 CSP lists allowed sources
↓
2 Browser refuses others
↓
3 Nonce lets your inline pass
↓
4 Frame options deny embedding
Why this works
CSP is a whitelist

A CSP is a list of allowed sources per type (scripts, styles, frames, images). The browser refuses anything outside it, so even an injected tag cannot pull in a remote script. It is the enforcement layer above escaping.

Nonce, not wildcard

Reaching for 'unsafe-inline' or * to make CSP 'work' undoes it, that is the same as no policy. Use a per-response nonce for the inline blocks you actually need. A policy that needs unsafe-inline is a policy not yet written.

Examples

The policy

Content-Security-Policy:
  script-src 'self';
  style-src 'self' 'nonce-abc123';

This says: run scripts only from our own origin, and inline styles only if they carry the nonce. Anything else is blocked.

Nonce for inline

<style nonce="abc123">

A per-response random nonce lets the one inline block you wrote pass, while a forged inline block without the nonce is refused. Random per page, so it cannot be copied.

Frame denial

X-Frame-Options: DENY

Refuse to be framed, so another site cannot put your page in an iframe to trick a user into clicking. This closes clickjacking.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← The wire is not safe
Previous Lesson
The wire is not safe
Next Lesson
Handing over access safely
Handing over access safely →