Skip to content

Security

Content Security Policy: what to verify before client handoff

Before handoff, confirm the launch URLs send a CSP that actually restricts content sources, match www and apex, and separate report-only from enforcing—then rescan instead of trusting staging.

· by Henry Smith

Content Security Policy: what to verify before client handoff

I still forget to check CSP until a security-minded client asks about headers on the handoff call. By then the brand deck is done and the CDN ticket queue is not. Better habit: treat Content Security Policy as a named checkbox beside HSTS, not as optional polish.

SlaySlop's CSP check "Checks whether browser content sources are restricted by a CSP header." That is the bar I use. Not "we talked about CSP in Slack once."

Outcome before you hand the keys over

Launch URLs the client will click—home, pricing, signup, checkout—either show a restricting CSP header or have an explicit, accepted risk note. Report-only is labeled as report-only. Apex and www match if both are live. A follow-up scan agrees with your notes.

I also want one named owner. CDN, app platform, or tag manager. "Someone on infra" is how the header disappears again after the first marketing experiment.

Boundaries

Permissioned, read-only scanning. Not a pentest. CSP is not the XSS check. HSTS is a sibling, not a substitute: it "Checks whether browsers are instructed to keep future requests on HTTPS." Frame protection is another sibling. I keep them on one checklist so I do not declare victory after a single header.

SlaySlop will not flip your CDN toggle. I still reach for curl first when I am verifying a change I just requested:

bash
for u in   "https://example.com/"   "https://www.example.com/"   "https://www.example.com/checkout"
do
  echo "== $u"
  curl -sI "$u" | rg -i 'HTTP/|content-security-policy|strict-transport|x-frame'
done

Loading diagram.

Happy path checklist

  1. URL list. Write the five URLs you will demo. Scans follow discovery; your demo path still needs an explicit pass.
  2. Header present. Look for Content-Security-Policy. If you only see Content-Security-Policy-Report-Only, write that down honestly.
  3. Restriction is real. A header that allows every script host you can imagine—and 'unsafe-inline' / 'unsafe-eval' without a plan—may still fail the spirit of "restricted." Read the policy once. Do not argue from the header name alone.
  4. Hosts match. Preview, apex, www, and checkout subdomain often disagree. I have shipped with CSP on www only. Clients notice when they type the apex.
  5. Siblings. HSTS and frame headers in the same tab.
  6. Rescan. SlaySlop follow-up scans exist so you can check whether the issue is actually gone.
text
Handoff CSP checklist
owner:
urls:
csp_enforcing: yes|no
csp_report_only: yes|no
hsts: yes|no
frame: yes|no
slayslop_rescan: pass|fail
notes:

Pitfalls I still create

Trusting staging edge rules. Accepting "the platform default is fine" without reading the live response. Tightening CSP after handoff without watching Console errors—broken tags throw, and then the client thinks you shipped a JS regression instead of a security header. Skipping checkout because "it's the same app" when the edge path differs.

Another one: putting the policy only in a meta tag on some CMSes while the Security check language focuses on a CSP header. If your platform documents a different delivery mechanism, verify what the browser actually receives on the public URL and keep the ticket precise.

I also still under-communicate report-only. Stakeholders hear "CSP is on" and stop listening. Say "report-only" out loud in the call if that is the truth.

What I write in the portal

Short, dull, useful:

text
CSP: enforcing header present on /, /pricing, /checkout (see scan).
HSTS: present.
Residual: tag manager allowlist owned by marketing; change window Tuesday.

No adjectives. Soft product note only when it helps: the shared SlaySlop report keeps the CSP row next to the same URLs the client already reviewed for SEO and uptime, which beats three disconnected screenshots.

Timing relative to content freeze

I try to lock CSP before the final tag-manager binge. If marketing still has three experiments to add, I schedule a second header pass after those land. Otherwise we hand over a restricting policy that gets deleted at 11pm to unblock a pixel, and the scan from the afternoon becomes fiction.

Smoke test I run after the CDN ticket closes

Same three curls as above. Same SlaySlop rescan. If either disagrees, the handoff is not done. I have been burned by "propagating" as an excuse for a mis-attached rule.

Related next step

If CSP is clean, keep going through the Security header set, then confirm Console errors stayed quiet after the policy tightened. Glossary: Content Security Policy.