diff --git a/changelog/fragments/pr-30356.md b/changelog/fragments/pr-30356.md new file mode 100644 index 00000000000..1fbff31c38e --- /dev/null +++ b/changelog/fragments/pr-30356.md @@ -0,0 +1 @@ +- Security/Media route: add `X-Content-Type-Options: nosniff` header regression assertions for successful and not-found media responses (#30356) (thanks @13otKmdr) diff --git a/src/media/server.test.ts b/src/media/server.test.ts index 9db1a1bac2d..a4c99139341 100644 --- a/src/media/server.test.ts +++ b/src/media/server.test.ts @@ -61,6 +61,7 @@ describe("media server", () => { const file = await writeMediaFile("file1", "hello"); const res = await fetch(mediaUrl("file1")); expect(res.status).toBe(200); + expect(res.headers.get("x-content-type-options")).toBe("nosniff"); expect(await res.text()).toBe("hello"); await waitForFileRemoval(file); }); @@ -113,6 +114,7 @@ describe("media server", () => { it("returns not found for missing media IDs", async () => { const res = await fetch(mediaUrl("missing-file")); expect(res.status).toBe(404); + expect(res.headers.get("x-content-type-options")).toBe("nosniff"); expect(await res.text()).toBe("not found"); }); diff --git a/src/media/server.ts b/src/media/server.ts index cdd1d27e366..b8982cb690a 100644 --- a/src/media/server.ts +++ b/src/media/server.ts @@ -33,6 +33,7 @@ export function attachMediaRoutes( const mediaDir = getMediaDir(); app.get("/media/:id", async (req, res) => { + res.setHeader("X-Content-Type-Options", "nosniff"); const id = req.params.id; if (!isValidMediaId(id)) { res.status(400).send("invalid path");