From 4a4e60aa99c2fc608508a5cec55be2c6be912087 Mon Sep 17 00:00:00 2001 From: Jeff <138259519+jdotc1@users.noreply.github.com> Date: Sun, 8 Nov 2026 21:46:57 -0500 Subject: [PATCH 1/3] test(security): add regression coverage before remediation --- src/__tests__/docker-security.test.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/__tests__/docker-security.test.ts diff --git a/src/__tests__/docker-security.test.ts b/src/__tests__/docker-security.test.ts new file mode 100644 index 0000000..5ebce9b --- /dev/null +++ b/src/__tests__/docker-security.test.ts @@ -0,0 +1,21 @@ +import { readFileSync } from "node:fs"; +import { join } from "node:path"; + +describe("Docker build context security", () => { + const read = (file: string) => readFileSync(join(process.cwd(), file), "utf8"); + + it("excludes local environment secrets from image build contexts", () => { + const ignored = read(".dockerignore") + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith("#")); + + expect(ignored).toContain(".env"); + expect(ignored).toContain(".env*.local"); + }); + + it("runs the development image as the unprivileged node user", () => { + const developmentStage = read("Dockerfile").split("FROM node:lts-alpine AS build")[0]; + expect(developmentStage).toMatch(/^USER node$/m); + }); +}); From 332007248e33cb97d08a4285c0b42bb6fe7e36bd Mon Sep 17 00:00:00 2001 From: Jeff <138259519+jdotc1@users.noreply.github.com> Date: Sun, 8 Nov 2026 21:47:43 -0500 Subject: [PATCH 2/3] fix(security): exclude secrets and run dev image without root (#279) --- .dockerignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.dockerignore b/.dockerignore index 0d7c2da..f0c533b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,5 @@ +.env +.env*.local node_modules/ .next/ .git/ From 469f10d946b08788754c7871194a56cbafd41b18 Mon Sep 17 00:00:00 2001 From: Jeff <138259519+jdotc1@users.noreply.github.com> Date: Sun, 8 Nov 2026 21:47:45 -0500 Subject: [PATCH 3/3] fix(security): exclude secrets and run dev image without root (#279) --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 0c263bc..f26d63a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,7 +25,8 @@ RUN npm ci COPY --chown=node:node . . # Use the node user from the image (instead of the root user) -# USER node +RUN chown node:node /usr/src/app +USER node # For container development, the following command runs forever, so we can inspect the container CMD ["npm", "run", ".dev"]