diff --git a/middlewares/security_headers.ts b/middlewares/security_headers.ts new file mode 100644 index 00000000..968fe734 --- /dev/null +++ b/middlewares/security_headers.ts @@ -0,0 +1,28 @@ +// Copyright 2023-2025 the Deno authors. All rights reserved. MIT license. +import type { FreshContext } from "$fresh/server.ts"; + +export default async (_req: Request, ctx: FreshContext): Promise => { + if (ctx.destination !== "route" || ctx.url.pathname.startsWith("/api")) { + return await ctx.next(); + } + + const response = await ctx.next(); + + /** + * @todo(Jabolol) Implement `Content-Security-Policy` once + * https://github.com/denoland/fresh/pull/1787 lands. + */ + response.headers.set( + "Strict-Transport-Security", + "max-age=63072000;", + ); + response.headers.set( + "Referrer-Policy", + "strict-origin-when-cross-origin", + ); + response.headers.set("X-Content-Type-Options", "nosniff"); + response.headers.set("X-Frame-Options", "SAMEORIGIN"); + response.headers.set("X-XSS-Protection", "1; mode=block"); + + return response; +}; diff --git a/plugins/security_headers.ts b/plugins/security_headers.ts index 7953f5a7..7a3ee062 100644 --- a/plugins/security_headers.ts +++ b/plugins/security_headers.ts @@ -1,5 +1,6 @@ // Copyright 2023-2025 the Deno authors. All rights reserved. MIT license. import type { Plugin } from "$fresh/server.ts"; +import securityHeadersMiddleware from "../middlewares/security_headers.ts"; export default { name: "security-headers", @@ -7,32 +8,7 @@ export default { { path: "/", middleware: { - handler: async (req, ctx) => { - if ( - ctx.destination !== "route" || - new URL(req.url).pathname.startsWith("/api") - ) return await ctx.next(); - - const response = await ctx.next(); - - /** - * @todo(Jabolol) Implement `Content-Security-Policy` once - * https://github.com/denoland/fresh/pull/1787 lands. - */ - response.headers.set( - "Strict-Transport-Security", - "max-age=63072000;", - ); - response.headers.set( - "Referrer-Policy", - "strict-origin-when-cross-origin", - ); - response.headers.set("X-Content-Type-Options", "nosniff"); - response.headers.set("X-Frame-Options", "SAMEORIGIN"); - response.headers.set("X-XSS-Protection", "1; mode=block"); - - return response; - }, + handler: securityHeadersMiddleware, }, }, ],