I'm having trouble implementing Content Security Policy (CSP) with nonces using Vite for asset building. Here's the situation:
I'm using the Spatie CSP package to set up my CSP. My policy is configured to use nonces for scripts and styles.
public function configure(): void
{
$this
->addDirective(Directive::BASE, Keyword::SELF)
->addDirective(Directive::CONNECT, Keyword::SELF)
->addDirective(Directive::DEFAULT, Keyword::SELF)
->addDirective(Directive::FORM_ACTION, Keyword::SELF)
->addDirective(Directive::IMG, Keyword::SELF)
->addDirective(Directive::MEDIA, Keyword::SELF)
->addDirective(Directive::OBJECT, Keyword::NONE)
->addDirective(Directive::SCRIPT, [Keyword::SELF, 'https://app.domain.com', 'https://domain.com'])
->addDirective(Directive::STYLE, [Keyword::SELF, 'https://fonts.bunny.net'])
->addDirective(Directive::FONT, [Keyword::SELF, 'https://fonts.bunny.net'])
->addDirective(Directive::FRAME, Keyword::NONE)
->addDirective(Directive::WORKER, Keyword::SELF)
->addDirective(Directive::MANIFEST, Keyword::SELF)
->addNonceForDirective(Directive::SCRIPT)
->addNonceForDirective(Directive::STYLE);
}
In development, everything works fine - a new nonce is generated for each request.
However, after building assets with Vite (npm run build), I get CSP errors in production.
The main issue seems to be that the nonce generated for the CSP header doesn't match the nonce in the built script tags. This is because Vite can't inject the dynamically generated nonce into the built files.
Has anyone successfully implemented CSP with nonces in a Laravel + Vite setup?