From b8105b03073d329f7338c10c00ff317a4a26c572 Mon Sep 17 00:00:00 2001 From: maxgfr <25312957+maxgfr@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:46:55 +0200 Subject: [PATCH 1/3] fix: extension --- targets/frontend/src/lib/secu.ts | 2 +- targets/frontend/src/pages/api/storage/index.ts | 17 ++++++++--------- targets/frontend/src/pages/fichiers.tsx | 8 ++++++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/targets/frontend/src/lib/secu.ts b/targets/frontend/src/lib/secu.ts index a7745ebed..6e2ef05b7 100644 --- a/targets/frontend/src/lib/secu.ts +++ b/targets/frontend/src/lib/secu.ts @@ -21,7 +21,7 @@ const isAllowedFile = (file: formidable.File) => { .split(".") .reverse()[0]; if (!extension) return false; - return ALLOWED_EXTENSIONS.includes(extension); + return ALLOWED_EXTENSIONS.includes("." + extension); }; export const isUploadFileSafe = (file: formidable.File): Promise => { diff --git a/targets/frontend/src/pages/api/storage/index.ts b/targets/frontend/src/pages/api/storage/index.ts index 7c1c09613..52bb5487b 100644 --- a/targets/frontend/src/pages/api/storage/index.ts +++ b/targets/frontend/src/pages/api/storage/index.ts @@ -1,22 +1,19 @@ -import Boom from "@hapi/boom"; import formidable, { IncomingForm } from "formidable"; -import { createErrorFor } from "src/lib/apiError"; import { isUploadFileSafe } from "src/lib/secu"; import { NextApiRequest, NextApiResponse } from "next"; import { getApiAllFiles, uploadApiFiles } from "src/lib/upload"; import fs from "fs"; async function endPoint(req: NextApiRequest, res: NextApiResponse) { - const apiError = createErrorFor(res); - switch (req.method) { case "POST": return uploadFiles(req, res); case "GET": return getFiles(req, res); default: { - res.setHeader("Allow", "GET, POST"); - apiError(Boom.methodNotAllowed(`${req.method} not allowed`)); + return res + .status(400) + .json({ success: false, errorMessage: `${req.method} not allowed` }); } } } @@ -34,14 +31,16 @@ function uploadFiles(req: NextApiRequest, res: NextApiResponse) { const file = allFiles[i]; const isSafe = await isUploadFileSafe(file); if (!isSafe) { - console.error("A malicious code was find in the upload"); - return res.status(400).json({ success: false }); + console.error("Malicious code detected"); + return res + .status(400) + .json({ success: false, errorMessage: "Malicious code detected" }); } const fileContent = fs.readFileSync(file.filepath); await uploadApiFiles(`${file.originalFilename}`, fileContent); } + res.status(200).json({ success: true }); }); - res.status(200).json({ success: true }); } async function getFiles(_req: NextApiRequest, res: NextApiResponse) { diff --git a/targets/frontend/src/pages/fichiers.tsx b/targets/frontend/src/pages/fichiers.tsx index 94d93e8a6..66ba340af 100644 --- a/targets/frontend/src/pages/fichiers.tsx +++ b/targets/frontend/src/pages/fichiers.tsx @@ -66,8 +66,12 @@ function FilesPage() { mutate(); }, 3000); }) - .catch(() => { - alert("Impossible de supprimer le fichier :/"); + .catch((err) => { + console.log(JSON.stringify(err)); + alert( + "Impossible de supprimer le fichier :/, le message d'erreur est : " + + JSON.stringify(err.data.errorMessage) + ); }) .finally(() => { setUploading(false); From 4d21e0bcbe5928523eda1cb966505511a31da457 Mon Sep 17 00:00:00 2001 From: maxgfr <25312957+maxgfr@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:55:13 +0200 Subject: [PATCH 2/3] fix: extension --- .../frontend/src/lib/__tests__/secu.test.ts | 77 +++++++++++++++++++ targets/frontend/src/lib/secu.ts | 2 +- 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 targets/frontend/src/lib/__tests__/secu.test.ts diff --git a/targets/frontend/src/lib/__tests__/secu.test.ts b/targets/frontend/src/lib/__tests__/secu.test.ts new file mode 100644 index 000000000..89342b49f --- /dev/null +++ b/targets/frontend/src/lib/__tests__/secu.test.ts @@ -0,0 +1,77 @@ +import { isUploadFileSafe, isAllowedFile } from "../secu"; +import * as formidable from "formidable"; +import fs from "fs"; + +jest.mock("fs"); + +describe("secu.ts", () => { + describe("isAllowedFile", () => { + test("should return true for allowed extensions", () => { + const file: formidable.File = { + originalFilename: "test.png", + } as formidable.File; + + expect(isAllowedFile(file)).toBe(true); + }); + + test("should return false for disallowed extensions", () => { + const file: formidable.File = { + originalFilename: "test.exe", + } as formidable.File; + + expect(isAllowedFile(file)).toBe(false); + }); + + test("should return false if filename is undefined", () => { + const file: formidable.File = { + originalFilename: undefined, + } as any; + + expect(isAllowedFile(file)).toBe(false); + }); + }); + + describe("isUploadFileSafe", () => { + test("should resolve false for disallowed file extensions", async () => { + const file: formidable.File = { + originalFilename: "test.exe", + mimetype: "application/octet-stream", + } as formidable.File; + + await expect(isUploadFileSafe(file)).resolves.toBe(false); + }); + + test("should resolve true for non-SVG file types", async () => { + const file: formidable.File = { + originalFilename: "test.png", + mimetype: "image/png", + } as formidable.File; + + await expect(isUploadFileSafe(file)).resolves.toBe(true); + }); + + test("should resolve true for SVG files without script tags", async () => { + (fs.readFileSync as jest.Mock).mockReturnValue(""); + + const file: formidable.File = { + originalFilename: "test.svg", + mimetype: "image/svg+xml", + } as formidable.File; + + await expect(isUploadFileSafe(file)).resolves.toBe(true); + }); + + test("should resolve false for SVG files with script tags", async () => { + (fs.readFileSync as jest.Mock).mockReturnValue( + '' + ); + + const file: formidable.File = { + originalFilename: "test.svg", + mimetype: "image/svg+xml", + } as formidable.File; + + await expect(isUploadFileSafe(file)).resolves.toBe(false); + }); + }); +}); diff --git a/targets/frontend/src/lib/secu.ts b/targets/frontend/src/lib/secu.ts index 6e2ef05b7..4de59b5c5 100644 --- a/targets/frontend/src/lib/secu.ts +++ b/targets/frontend/src/lib/secu.ts @@ -15,7 +15,7 @@ const ALLOWED_EXTENSIONS = [ ...ALLOWED_DOC, ]; -const isAllowedFile = (file: formidable.File) => { +export const isAllowedFile = (file: formidable.File) => { const extension = file.originalFilename ?.toLowerCase() .split(".") From f9ca336380b2ef659c4672082573aa53f378231b Mon Sep 17 00:00:00 2001 From: maxgfr <25312957+maxgfr@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:56:19 +0200 Subject: [PATCH 3/3] fix: extension --- targets/frontend/src/pages/fichiers.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/targets/frontend/src/pages/fichiers.tsx b/targets/frontend/src/pages/fichiers.tsx index 66ba340af..69d6bce9a 100644 --- a/targets/frontend/src/pages/fichiers.tsx +++ b/targets/frontend/src/pages/fichiers.tsx @@ -67,10 +67,9 @@ function FilesPage() { }, 3000); }) .catch((err) => { - console.log(JSON.stringify(err)); alert( "Impossible de supprimer le fichier :/, le message d'erreur est : " + - JSON.stringify(err.data.errorMessage) + JSON.stringify(err.data) ); }) .finally(() => {