diff --git a/app/layout.tsx b/app/layout.tsx index ddce888..71bd50f 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -134,7 +134,7 @@ export default async function RootLayout({
diff --git a/lib/csp-server.ts b/lib/csp-server.ts index 6b99543..2813bc0 100644 --- a/lib/csp-server.ts +++ b/lib/csp-server.ts @@ -52,9 +52,12 @@ export function buildCSP(config: CSPConfig = {}): string { : ["'self'"]; // Style sources - use nonce in production when available - const styleSrc = nonce - ? ["'self'", `'nonce-${nonce}'`] - : ["'self'", "'unsafe-inline'"]; // Fallback for TailwindCSS + // Note: We need 'unsafe-inline' for third-party libraries like Sonner that inject styles dynamically + const styleSrc = isDevelopment + ? ["'self'", "'unsafe-inline'"] + : nonce + ? ["'self'", `'nonce-${nonce}'`, "'unsafe-inline'"] // Need unsafe-inline for Sonner/Leaflet + : ["'self'", "'unsafe-inline'"]; // Fallback for TailwindCSS // Image sources - allow self, data URIs, and specific trusted domains const imgSrc = [ @@ -69,8 +72,8 @@ export function buildCSP(config: CSPConfig = {}): string { .map((domain) => domain), ].filter(Boolean); - // Font sources - restrict to self and data URIs - const fontSrc = ["'self'", "data:"]; + // Font sources - restrict to self, data URIs, and Google Fonts (for Leaflet) + const fontSrc = ["'self'", "data:", "https://fonts.gstatic.com"]; // Connect sources - API endpoints and trusted domains const connectSrc = isDevelopment diff --git a/lib/nonce-utils.ts b/lib/nonce-utils.ts index 6115711..6c98c41 100644 --- a/lib/nonce-utils.ts +++ b/lib/nonce-utils.ts @@ -6,9 +6,21 @@ import { headers } from "next/headers"; export async function getNonce(): Promise