Content Security Policies (CSP) are an often overlooked security tool when building your website.
CSPs are like a security guard for your website. It tells the browser what’s allowed to load—like which scripts, images, or styles are safe—and blocks everything else. This helps stop hackers from sneaking in bad code (like XSS attacks, clickjacking attempts and more).
I’ve been using Spatie’s Laravel CSP package to produce the CSP Headers for my applications for a while now. One of the big annoyances is when a third party service uses several different domain names to make their outgoing. Hubspot is a particularly evil culprit of this.
Enter: Presets
Earlier this year, version 3 of the Laravel CSP package was released, and takes are of exactly this problem. They now offer presets for common services, so you can specify the preset rather than each individual domain.
For example, in my config/csp.php
file, I’m including Presets from Spatie for HubSpot, PostHog and Buny Fonts. I’m also including my application’s custom policy for resources that aren’t covered by the presets.
<?php
return [
'presets' => [
\Spatie\Csp\Presets\HubSpot::class,
\Spatie\Csp\Presets\Posthog::class,
\Spatie\Csp\Presets\BunnyFonts::class,
App\Support\AppCspPolicy::class,
],
The Hubspot Preset, as a perfect example, allows you to, using this one line, include what would have littered your policy with this, previously:
<?php
$policy
->add(Directive::SCRIPT, '*.hsadspixel.net')
->add(Directive::SCRIPT, '*.hs-analytics.net')
->add(Directive::CONNECT, '*.hubapi.com')
->add([Directive::SCRIPT, Directive::IMG, Directive::CONNECT], [
'js.hscta.net',
'js-eu1.hscta.net',
])
->add(Directive::IMG, 'no-cache.hubspot.com')
->add([Directive::SCRIPT, Directive::IMG, Directive::CONNECT, Directive::FRAME], '*.hubspot.com')
->add(Directive::FRAME, [
'*.hs-sites.com',
'*.hs-sites-eu1.com',
])
->add(Directive::SCRIPT, 'static.hsappstatic.net')
->add(Directive::SCRIPT, '*.usemessages.com')
->add([Directive::SCRIPT, Directive::CONNECT], '*.hs-banner.com')
->add([Directive::SCRIPT, Directive::IMG, Directive::STYLE], [
'*.hubspotusercontent00.net',
'*.hubspotusercontent10.net',
'*.hubspotusercontent20.net',
'*.hubspotusercontent30.net',
'*.hubspotusercontent40.net',
])
->add([Directive::SCRIPT, Directive::IMG, Directive::FRAME], '*.hubspot.net')
->add(Directive::FRAME, [
'play.hubspotvideo.com',
'play-eu1.hubspotvideo.com',
])
->add([Directive::IMG, Directive::STYLE], 'cdn2.hubspot.net')
->add([Directive::SCRIPT, Directive::CONNECT], '*.hscollectedforms.net')
->add(Directive::SCRIPT, '*.hsleadflows.net')
->add([Directive::SCRIPT, Directive::IMG, Directive::FRAME], '*.hsforms.net')
->add([Directive::SCRIPT, Directive::IMG, Directive::FRAME, Directive::CONNECT, Directive::CHILD], '*.hsforms.com')
->add(Directive::SCRIPT, '*.hs-scripts.com')
->add(Directive::SCRIPT, '*.hubspotfeedback.com')
->add(Directive::SCRIPT, 'feedback.hubapi.com')
->add(Directive::SCRIPT, 'feedback-eu1.hubapi.com');
}
}
Not a bad improvement, eh?
There’s a growing number of Presets available in the plugin. You can see the full list here:
github.com/spatie/laravel-csp/tree/main/src/Presets
You can even contribute your own.
Thank you, team Spatie, for making CSP’s much easier to implement for Laravel developers.