Skip to content

Commit

Permalink
feat: harden headers security (denoland#592)
Browse files Browse the repository at this point in the history
Work in progress. See denoland#591 for the relevant discussion.

---------

Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
  • Loading branch information
Jabolol and iuioiua authored Sep 22, 2023
1 parent 069a09a commit d3bc49b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
2 changes: 2 additions & 0 deletions fresh.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import twindConfig from "./twind.config.ts";
import kvOAuthPlugin from "./plugins/kv_oauth.ts";
import sessionPlugin from "./plugins/session.ts";
import errorHandling from "./plugins/error_handling.ts";
import securityHeaders from "./plugins/security_headers.ts";
import { FreshOptions } from "$fresh/server.ts";

export default {
Expand All @@ -12,5 +13,6 @@ export default {
sessionPlugin,
twindPlugin(twindConfig),
errorHandling,
securityHeaders,
],
} as FreshOptions;
36 changes: 36 additions & 0 deletions plugins/security_headers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import { type Plugin } from "$fresh/server.ts";

export default {
name: "security-headers",
middlewares: [
{
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;
},
},
},
],
} as Plugin;
23 changes: 23 additions & 0 deletions plugins/security_headers_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import { createHandler } from "$fresh/server.ts";
import { assertEquals } from "std/assert/assert_equals.ts";
import manifest from "@/fresh.gen.ts";
import options from "@/fresh.config.ts";

const handler = await createHandler(manifest, options);

Deno.test("[middleware] security headers are present", async () => {
const resp = await handler(new Request("http://localhost"));

assertEquals(
resp.headers.get("strict-transport-security"),
"max-age=63072000;",
);
assertEquals(
resp.headers.get("referrer-policy"),
"strict-origin-when-cross-origin",
);
assertEquals(resp.headers.get("x-content-type-options"), "nosniff");
assertEquals(resp.headers.get("x-frame-options"), "SAMEORIGIN");
assertEquals(resp.headers.get("x-xss-protection"), "1; mode=block");
});

0 comments on commit d3bc49b

Please sign in to comment.