From 4199070dfdb22dae15e0ceb3f2c015c81ddd8f6f Mon Sep 17 00:00:00 2001 From: matthieu42morin Date: Mon, 29 Apr 2024 05:02:00 +0200 Subject: [PATCH] csp, hooks, sentry --- src/cspDirectives.ts | 146 +++++++++++++++++++++---------------------- src/hooks.server.ts | 52 +++++++-------- src/lib/constants.ts | 9 +++ 3 files changed, 108 insertions(+), 99 deletions(-) create mode 100644 src/lib/constants.ts diff --git a/src/cspDirectives.ts b/src/cspDirectives.ts index 9ee6619..e8cada4 100644 --- a/src/cspDirectives.ts +++ b/src/cspDirectives.ts @@ -1,83 +1,83 @@ // https://gist.github.com/acoyfellow/d8e86979c66ebea25e1643594e38be73, Rodney Lab import { - PUBLIC_SITE_DOMAIN, - PUBLIC_SENTRY_KEY, - PUBLIC_SENTRY_PROJECT_ID, - PUBLIC_SENTRY_ORG_ID, - PUBLIC_WORKER_URL + URARA_SITE_DOMAIN, + PUBLIC_SENTRY_KEY, + PUBLIC_SENTRY_PROJECT_ID, + PUBLIC_SENTRY_ORG_ID, + PUBLIC_WORKER_URL, + URARA_SITE_PROTOCOL } from '$env/static/public' -const rootDomain = PUBLIC_SITE_DOMAIN // or your server IP for dev +console.log(`${URARA_SITE_PROTOCOL}${URARA_SITE_DOMAIN}`) const directives = { - 'base-uri': ["'self'"], - 'child-src': ["'self'", 'blob:'], - // 'connect-src': ["'self'", 'ws://localhost:*'], - 'connect-src': [ - "'self'", - 'ws://localhost:*', - 'https://*.sentry.io', - 'https://hcaptcha.com', - 'https://*.hcaptcha.com', - 'https://*.cartocdn.com', - PUBLIC_SITE_DOMAIN, - PUBLIC_WORKER_URL - ], - 'img-src': ["'self'", 'data:', 'https://images.unsplash.com'], - 'font-src': ["'self'", 'data:'], - 'form-action': ["'self'"], - 'frame-ancestors': ["'self'"], - 'frame-src': [ - "'self'", - // "https://*.stripe.com", - // "https://*.facebook.com", - // "https://*.facebook.net", - 'https://hcaptcha.com', - 'https://*.hcaptcha.com', - 'https://www.openstreetmap.org', - 'https://*.cartocdn.com' - ], - 'manifest-src': ["'self'"], - 'media-src': ["'self'", 'data:'], - 'object-src': ["'none'"], - // 'style-src': ["'self'", "'unsafe-inline'"], - 'style-src': ["'self'", "'unsafe-inline'", 'https://hcaptcha.com', 'https://*.hcaptcha.com'], - 'default-src': [ - "'self'", - PUBLIC_SITE_DOMAIN, - `ws://${PUBLIC_SITE_DOMAIN}`, - // 'https://*.google.com', - // 'https://*.googleapis.com', - // 'https://*.firebase.com', - // 'https://*.gstatic.com', - // 'https://*.cloudfunctions.net', - // 'https://*.algolia.net', - // 'https://*.facebook.com', - // 'https://*.facebook.net', - // 'https://*.stripe.com', - 'https://*.sentry.io' - ], - 'script-src': [ - "'self'", - "'unsafe-inline'", - // 'https://*.stripe.com', - // 'https://*.facebook.com', - // 'https://*.facebook.net', - 'https://hcaptcha.com', - 'https://*.hcaptcha.com', - 'https://*.sentry.io', - // 'https://polyfill.io', - 'https://*.cartocdn.com' - ], - 'worker-src': ["'self'", 'blob:'], - //report-to can throw "Content-Security-Policy: Couldn’t process unknown directive ‘report-to’", leave it for older browsers. - 'report-to': ["'csp-endpoint'"], - 'report-uri': [ - `https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}` - ] + 'base-uri': ["'self'"], + 'child-src': ["'self'", 'blob:'], + 'connect-src': [ + "'self'", + 'ws://localhost:*', + 'https://*.sentry.io', + 'https://hcaptcha.com', + 'https://*.hcaptcha.com', + 'https://*.cartocdn.com', + URARA_SITE_DOMAIN, + PUBLIC_WORKER_URL + ], + 'img-src': ["'self'", 'data:', 'https://images.unsplash.com', `${URARA_SITE_PROTOCOL}${URARA_SITE_DOMAIN}`], + 'font-src': ["'self'", 'data:'], + 'form-action': ["'self'"], + 'frame-ancestors': ["'self'"], + 'frame-src': [ + "'self'", + // "https://*.stripe.com", + // "https://*.facebook.com", + // "https://*.facebook.net", + 'https://hcaptcha.com', + 'https://*.hcaptcha.com', + 'https://www.openstreetmap.org', + 'https://*.cartocdn.com' + ], + 'manifest-src': ["'self'"], + 'media-src': ["'self'", 'data:'], + 'object-src': ["'none'"], + // 'style-src': ["'self'", "'unsafe-inline'"], + 'style-src': ["'self'", "'unsafe-inline'", 'https://hcaptcha.com', 'https://*.hcaptcha.com'], + 'default-src': [ + "'self'", + URARA_SITE_DOMAIN, + `ws://${URARA_SITE_DOMAIN}`, + // 'https://*.google.com', + // 'https://*.googleapis.com', + // 'https://*.firebase.com', + // 'https://*.gstatic.com', + // 'https://*.cloudfunctions.net', + // 'https://*.algolia.net', + // 'https://*.facebook.com', + // 'https://*.facebook.net', + // 'https://*.stripe.com', + 'https://*.sentry.io' + ], + 'script-src': [ + "'self'", + "'unsafe-inline'", + // 'https://*.stripe.com', + // 'https://*.facebook.com', + // 'https://*.facebook.net', + 'https://hcaptcha.com', + 'https://*.hcaptcha.com', + 'https://*.sentry.io', + // 'https://polyfill.io', + 'https://*.cartocdn.com' + ], + 'worker-src': ["'self'", 'blob:'], + //report-to can throw "Content-Security-Policy: Couldn’t process unknown directive ‘report-to’", leave it for older browsers. + 'report-to': ["'csp-endpoint'"], + 'report-uri': [ + `https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}` + ] } export const csp = Object.entries(directives) - .map(([key, arr]) => key + ' ' + arr.join(' ')) - .join('; ') + .map(([key, arr]) => key + ' ' + arr.join(' ')) + .join('; ') diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 1baed96..f8e8112 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -4,44 +4,44 @@ import { site } from '$lib/config/site' import { handleErrorWithSentry, sentryHandle } from '@sentry/sveltekit' import * as Sentry from '@sentry/sveltekit' -import { PUBLIC_SENTRY_KEY, PUBLIC_SENTRY_PROJECT_ID, PUBLIC_SENTRY_ORG_ID } from '$env/static/public' +import { PUBLIC_SENTRY_KEY, PUBLIC_SENTRY_PROJECT_ID, PUBLIC_SENTRY_ORG_ID, URARA_SITE_DOMAIN } from '$env/static/public' import { csp } from './cspDirectives' Sentry.init({ - dsn: `https://${PUBLIC_SENTRY_KEY}@${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/${PUBLIC_SENTRY_PROJECT_ID}`, - tracesSampleRate: 1.0 + dsn: `https://${PUBLIC_SENTRY_KEY}@${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/${PUBLIC_SENTRY_PROJECT_ID}`, + tracesSampleRate: 1.0 }) export const cspHandle: Handle = async ({ event, resolve }) => { - if (!csp) { - throw new Error('csp is undefined') - } - const response = await resolve(event) + if (!csp) { + throw new Error('csp is undefined') + } + const response = await resolve(event) - // Permission fullscreen necessary for maps fullscreen - const headers = { - 'X-Frame-Options': 'SAMEORIGIN', - 'Referrer-Policy': 'no-referrer', - 'Permissions-Policy': `accelerometer=(), autoplay=(), camera=(), document-domain=(self, 'js-profiling'), encrypted-media=(), fullscreen=(self ${PUBLIC_SITE_DOMAIN}), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), geolocation=()`, - 'X-Content-Type-Options': 'nosniff', - // 'Content-Security-Policy-Report-Only': csp, - 'Content-Security-Policy': csp, - 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', - 'Expect-CT': `max-age=86400, report-uri="https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}"`, - 'Report-To': `{group: "csp-endpoint", "max_age": 10886400, "endpoints": [{"url": "https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}"}]}` - } + // Permission fullscreen necessary for maps fullscreen + const headers = { + 'X-Frame-Options': 'SAMEORIGIN', + 'Referrer-Policy': 'no-referrer', + 'Permissions-Policy': `accelerometer=(), autoplay=(), camera=(), document-domain=(self, 'js-profiling'), encrypted-media=(), fullscreen=(self ${URARA_SITE_DOMAIN}), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), geolocation=()`, + 'X-Content-Type-Options': 'nosniff', + // 'Content-Security-Policy-Report-Only': csp, + 'Content-Security-Policy': csp, + 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload', + 'Expect-CT': `max-age=86400, report-uri="https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}"`, + 'Report-To': `{group: "csp-endpoint", "max_age": 10886400, "endpoints": [{"url": "https://${PUBLIC_SENTRY_ORG_ID}.ingest.us.sentry.io/api/${PUBLIC_SENTRY_PROJECT_ID}/security/?sentry_key=${PUBLIC_SENTRY_KEY}"}]}` + } - Object.entries(headers).forEach(([key, value]) => { - response.headers.set(key, value) - }) - return response + Object.entries(headers).forEach(([key, value]) => { + response.headers.set(key, value) + }) + return response } export const langHandle: Handle = async ({ event, resolve }) => - await resolve(event, { - transformPageChunk: ({ html }) => html.replace('', ``) - }) + await resolve(event, { + transformPageChunk: ({ html }) => html.replace('', ``) + }) // If you have custom handlers, make sure to place them after `sentryHandle()` in the `sequence` function. export const handle: Handle = sequence(sentryHandle(), cspHandle, langHandle) diff --git a/src/lib/constants.ts b/src/lib/constants.ts new file mode 100644 index 0000000..c9db6d8 --- /dev/null +++ b/src/lib/constants.ts @@ -0,0 +1,9 @@ +export const cookies = { + NECESSARY: 'mattmor-necessary', + ANALYTICAL: 'mattmor-analytical', + TARGETING: 'mattmor-targeting', + VISITED: 'mattmor-marketing-website-visited' +}; +export const COPYRIGHT_ENTITY = '\u00a9'; // (c) +export const H_ELLIPSIS_ENTITY = '\u2026'; // ... +export const VERTICAL_LINE_ENTITY = '\u007c'; // |