Replace unsafe-inline with CSP nonces for script-src
SvelteKit now handles script-src with automatic nonces via its built-in CSP support. The hooks handler merges extra directives (style-src, font-src, img-src, etc.) onto SvelteKit's nonce-based policy for page responses, and sets a full CSP for API responses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+11
-1
@@ -100,7 +100,17 @@ export const handle: Handle = async ({ event, resolve }) => {
|
||||
response.headers.set('X-Content-Type-Options', 'nosniff');
|
||||
response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
||||
response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
|
||||
response.headers.set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' ws: wss:; frame-ancestors 'none'");
|
||||
// SvelteKit sets CSP with nonces on page responses via svelte.config.js.
|
||||
// For non-page responses (API, etc.) or to add directives SvelteKit doesn't cover, set our own.
|
||||
const existingCSP = response.headers.get('content-security-policy');
|
||||
if (existingCSP) {
|
||||
// SvelteKit set a CSP with script-src nonce — append our extra directives
|
||||
const extras = "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' ws: wss:; frame-ancestors 'none'";
|
||||
response.headers.set('Content-Security-Policy', `${existingCSP}; ${extras}`);
|
||||
} else {
|
||||
// Non-page response (API routes) — set full CSP without unsafe-inline
|
||||
response.headers.set('Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' ws: wss:; frame-ancestors 'none'");
|
||||
}
|
||||
response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()');
|
||||
|
||||
logger.info({
|
||||
|
||||
@@ -8,6 +8,12 @@ const config = {
|
||||
$components: 'src/lib/components',
|
||||
$server: 'src/lib/server',
|
||||
$utils: 'src/lib/utils'
|
||||
},
|
||||
csp: {
|
||||
directives: {
|
||||
'default-src': ['self'],
|
||||
'script-src': ['self']
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user