We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Legitimate Inline Scripts

Moving all your own JavaScript into same-origin external files is usually the simplest way to keep a strict CSP. When a trusted inline script really has to stay inline, authorize just that one script with a per-response nonce.

Generate a fresh, unpredictable value for every HTML response:

import { randomBytes } from "node:crypto";

const nonce = randomBytes(16).toString("base64");
res.locals.cspNonce = nonce;

Include the value in script-src:

Content-Security-Policy: script-src 'self' 'nonce-z7G4mN2qL8vP1sR5'

Then place the matching value on the trusted script element:

<script nonce="z7G4mN2qL8vP1sR5">
  window.location.assign("/receipts/42");
</script>

The browser only executes inline scripts that carry the nonce from that response's policy. An attacker who can inject markup can't predict the next nonce, and an old nonce doesn't authorize a script in a new response.

Never reuse a fixed nonce or accept one provided from the client's request.

Assignment

Bearly Secure already creates a fresh CSP nonce for every response and renders it on PawPal's trusted redirect script, but its policy ignores it. Allow only that nonce in script-src.

With Bearly Secure still running, run and submit the CLI tests from the project root.