From 906f31b2403137ac728e2c97bf9825c3fdd2d19f Mon Sep 17 00:00:00 2001 From: Julien Oculi Date: Thu, 4 Jul 2024 13:57:56 +0200 Subject: [PATCH] feat: :lock: update security from mozilla observatory report see https://developer.mozilla.org/en-US/observatory/analyze?host=lp36.fr.nf --- routes/_middleware.ts | 21 +++++++++++++++++++-- src/utils.ts | 4 ++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/routes/_middleware.ts b/routes/_middleware.ts index 4095e13..96c5cc7 100644 --- a/routes/_middleware.ts +++ b/routes/_middleware.ts @@ -9,6 +9,23 @@ export async function handler(request: Request, ctx: FreshContext) { // Get response const response = await ctx.next() + //Add security headers + // See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/TLS#http_strict_transport_security + response.headers.set('Strict-Transport-Security', 'max-age=63072000; includeSubDomains; preload') + response.headers.set('Content-Security-Policy', "frame-ancestors 'none'; upgrade-insecure-requests") + //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Referrer_policy + response.headers.set('Referrer-Policy', 'no-referrer, strict-origin-when-cross-origin') + //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/MIME_types + response.headers.set('X-Content-Type-Options', 'nosniff') + //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/Clickjacking + response.headers.set('X-Frame-Options', 'DENY') + //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/CORP + response.headers.set('Cross-Origin-Resource-Policy', 'same-origin') + //See https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity + //? SRI plugin for non local resources only ? + //See https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/CSP + //? fresh useCSP https://fresh.deno.dev/docs/examples/using-csp + // Allow service worker to serve root scope if (ctx.url.pathname.endsWith('island-startserviceworker.js')) { response.headers.set('Service-Worker-Allowed', '/') @@ -32,7 +49,7 @@ export async function handler(request: Request, ctx: FreshContext) { // Set session cookie setCookie(response.headers, { - name: '_SESSION', + name: '__Secure-SESSION', value: session.uuid, httpOnly: true, sameSite: 'Strict', @@ -46,7 +63,7 @@ export async function handler(request: Request, ctx: FreshContext) { session.set('_csrf', csrf) setCookie(response.headers, { - name: '_CSRF', + name: '__Host-CSRF', value: csrf, httpOnly: false, sameSite: 'Strict', diff --git a/src/utils.ts b/src/utils.ts index 62dd926..71c0c7a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -40,7 +40,7 @@ export async function requestApi< method: 'GET' | 'POST' | 'DELETE' | 'PATCH', payload?: Payload | null, ): Promise { - const csrf = getCookie('_CSRF') ?? '' + const csrf = getCookie('__Host-CSRF') ?? '' const base = new URL('/api/', location.origin) const endpoint = new URL( @@ -116,7 +116,7 @@ export async function* requestApiStream< method: 'GET' | 'POST' | 'DELETE' | 'PATCH', payload?: Payload | null, ): AsyncGenerator { - const csrf = getCookie('_CSRF') ?? '' + const csrf = getCookie('__Host-CSRF') ?? '' const base = new URL('/api/', location.origin) const endpoint = new URL(