Security Tip: Run Your CSP in Local Development!
[Tip #105] These are my top 3 tips for getting started with a Content Security Policy - as proven by a friend who went from failing security scans to passing with flying colours.

Last week I received a rather lovely email from a friend who I helped set up a Content Security Policy (CSP) for one of their clients:
![Hi Stephen Just wanted to say thanks again for your help with CSPs. [REDACTED] went live this morning after they ran a new scan on the site, and all passed with flying colours. The way you explained CSPs and how to use “report only” was amazing. I ended up creating their CSP in about half hour using report only in the console. Cheers](https://securinglaravel.com/content/images/2025/02/image-4.png)
Hi Stephen
Just wanted to say thanks again for your help with CSPs. [REDACTED] went live this morning after they ran a new scan on the site, and all passed with flying colours.
The way you explained CSPs and how to use “report only” was amazing. I ended up creating their CSP in about half hour using report only in the console.
Cheers
I found this very encouraging, as when my friend reached out, he had a CSP that was basically permitting everything because "everything broke when I tried to be more specific".
His CSP looked something like this:
Content-Security-Policy:
connect-src * ;
frame-src * ;
img-src * data: 'unsafe-inline' ;
script-src: * 'unsafe-inline' 'unsafe-eval' ;
style-src * 'unsafe-inline' ;
font-src * 'unsafe-inline' ;
frame-ancestors * data: blob: ;
Which defeats the entire purpose of having a CSP, and was causing security scans on his client's site to fail. So he reached out for my help, and these are the main things I taught him:
- Report-Only mode is your friend.
You can use CSPs either in blocking mode via theContent-Security-Policy
header, or report-only mode via theContent-Security-Policy-Report-Only
header. When you use report-only mode, the browser will still log all violations in the browser console and send them to yourreport-uri
endpoints, but it won't block anything. This allows you to build and test a restrictive CSP without the risk of breaking anything. You can also use them at the same time, and test a new policy while using an older one. - Run your CSP in local development.
Enable your CSP, pop open your browser console, and use/test/build your app in local dev. You'll see all violations are reported in the console, usually with suggestions for how to update your policy, which you can apply immediately. This gives you an incredibly fast feedback cycle, with no deployments needed. You'll also notice any new violations that pop up when you add new features to your app. - Use different CSPs for different parts of your app.
Your CSP doesn't need to encompass your entire app. The browser reads it on each request, so you can have a very restrictive CSP for your public and basic user pages, while opening things up for your admins that need some extra tools - or vice versa.
I love talking about CSPs, I hope those 3 tips help you started using them. If you have any CSP questions, please throw them my way, via the comments, email, or social media. We've also covered them a few times, so check out those articles too.
I'm also hoping to get a Laracon talk accepted about CSPs, and maybe this will be the year. 🤞
If you found this security tip useful, subscribe to get weekly Security Tips straight to your inbox. Upgrade to a premium subscription for exclusive monthly In Depth articles, or drop a coin in the tip jar to show your support.
When was the last time you had a penetration test? Book a Laravel Security Audit and Penetration Test, or a budget-friendly Security Review!
You can also connect with me on Bluesky, or other socials, and check out Practical Laravel Security, my interactive course designed to boost your Laravel security skills.