Security
Common Content Security Policy mistakes that still ship
Missing headers on checkout, report-only theater, and unsafe-inline everywhere still ship—while teams point at a CSP string that never restricted anything that mattered.
· by Maya Okonkwo

The mistakes that bother me are not exotic bypass research. They are ordinary shipping habits: no header on the money page, a report-only header sold as enforcement, or a policy so open it might as well be absent. An outsider reading response headers sees that immediately.
SlaySlop's Content Security Policy check "Checks whether browser content sources are restricted by a CSP header." The mistakes below are how teams still fail that public-surface test under green uptime.
Outcome if you fix these early
Fewer handoff calls where someone pastes a missing Content-Security-Policy line into chat. Tickets that name URLs. A habit of reading the policy text instead of celebrating that the header key exists.
What an attacker sees on the public surface is simple: either the browser received instructions about trusted content sources or it did not. Fancy internal roadmaps do not change that response.
Boundaries
Public read-only scanning. Permission required. Not a pentest. CSP ≠ XSS templates—Cross-site scripting is its own check using known vulnerability templates on public pages. HSTS and Frame protection are siblings; fix them in the same pass when you are already in the header tab. SlaySlop will not rewrite your CDN config.
Happy path: the mistakes I still see
Loading diagram.
Mistake 1: CSP on the blog, not on checkout
Marketing pages get the security review because they were in the first design QA. Checkout rides a different edge path and ships bare. Product examples on SlaySlop literally call out missing CSP on checkout-style coverage. Match that paranoia on every host that takes money or credentials.
curl -sI "https://www.example.com/blog/hello" | rg -i content-security-policy
curl -sI "https://www.example.com/checkout" | rg -i content-security-policyMistake 2: Report-Only sold as done
Content-Security-Policy-Report-Only is useful while you learn breakages. It is not the same as restricting content sources in the enforcing sense stakeholders hear when you say "we enabled CSP." Label it. Plan the cutover. Do not bury the distinction in a footnote.
Mistake 3: 'unsafe-inline' and 'unsafe-eval' as lifestyle choices
Sometimes you need a temporary exception. Often teams paste them permanently because a tag manager threw once. At that point the header still exists, but restriction is theater. Read script-src. If everything interesting is allowed, the public surface is still wide open to injection impact the policy was meant to narrow.
Mistake 4: Staging-only edge rules
Preview injects CSP; production does not. Or the reverse—production is tight and staging is loose, so engineers never feel the breakages. Verify the host the client types.
Mistake 5: Deleting the header to "fix" a broken widget
Console errors may spike when a new policy blocks a script. The wrong fix is removing CSP entirely. The right fix is allowlisting the specific host or changing how the script loads—then rescanning Console errors and CSP together.
BUG: CSP blocks payments.js on /checkout
header: enforcing
blocked: https://pay.vendor.example/sdk.js
action: add host to script-src; do not remove CSPMistake 6: Ignoring sibling headers
Shipping CSP while HSTS is absent—or while clickjacking protections are missing—leaves an odd story on the public surface. SlaySlop groups these under Security for a reason. Batch the work.
Mistake 7: Wiki evidence instead of response evidence
A Notion page titled "Our CSP standard" comforts project managers. Browsers do not fetch Notion. If curl -sI on production lacks the header, the standard is fiction.
Pitfalls that recreate the miss
Checking only apex when users land on www. Trusting a platform checkbox you never verified. Letting marketing add three new tag hosts without updating the policy. Treating Lighthouse from last quarter as continuous header monitoring. Closing the ticket from staging after production rolled back the edge config.
How I triage without drama
Missing CSP on checkout is urgent. A slightly loose img-src on a brochure site might wait. Still file both with URLs. Outsiders reading headers do not care which Slack channel owns the gap. Rank by where money and PII move.
Mistake 8: One global policy that lies about admin hosts
A single CDN policy pasted onto a marketing site and an internal tools hostname can be wrong for both. Either it breaks the tools or it is too open for the marketing checkout. Split policies by host when the app surfaces differ. The public checkout host is the one SlaySlop's Security story cares about in a customer-facing scan.
Related next step
Run a permissioned SlaySlop scan, read CSP beside HSTS and Frame protection, and fix the hollow policies before you celebrate the header name. Soft link: Content Security Policy.