21099 api serverside validation check
This commit is contained in:
@@ -1087,7 +1087,7 @@ export const RenderFileUpload = (field) => {
|
|||||||
setRejectedFiles([]); // Clear any previously rejected file errorsss
|
setRejectedFiles([]); // Clear any previously rejected file errorsss
|
||||||
};
|
};
|
||||||
|
|
||||||
const FILENAME_ALLOWED = /^[A-Za-z0-9 ._\-()]+$/;
|
const FILENAME_ALLOWED = /^[A-Za-z0-9 ._\-:()]+$/;
|
||||||
|
|
||||||
const validateFilename = (file, t) => {
|
const validateFilename = (file, t) => {
|
||||||
const name = file.name;
|
const name = file.name;
|
||||||
@@ -1112,8 +1112,8 @@ export const RenderFileUpload = (field) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// block characters < > : " / \ | ? *
|
// block characters < > " / \ | ? *
|
||||||
if (/[<>:"/\\|?*]/.test(name)) {
|
if (/[<>"/\\|?*]/.test(name)) {
|
||||||
return {
|
return {
|
||||||
code: "filename-invalid-chars",
|
code: "filename-invalid-chars",
|
||||||
message: `${name} ${t(
|
message: `${name} ${t(
|
||||||
|
|||||||
@@ -2175,7 +2175,7 @@ const RenderFileUpload = (field) => {
|
|||||||
setRejectedFiles([]); // Clear any previously rejected file errorsss
|
setRejectedFiles([]); // Clear any previously rejected file errorsss
|
||||||
};
|
};
|
||||||
|
|
||||||
const FILENAME_ALLOWED = /^[A-Za-z0-9 ._\-()]+$/;
|
const FILENAME_ALLOWED = /^[A-Za-z0-9 ._\-:()]+$/;
|
||||||
|
|
||||||
const validateFilename = (file, t) => {
|
const validateFilename = (file, t) => {
|
||||||
const name = file.name;
|
const name = file.name;
|
||||||
@@ -2190,7 +2190,6 @@ const RenderFileUpload = (field) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// broader blocklist (optional but recommended)
|
|
||||||
if (!FILENAME_ALLOWED.test(name)) {
|
if (!FILENAME_ALLOWED.test(name)) {
|
||||||
return {
|
return {
|
||||||
code: "filename-invalid-chars",
|
code: "filename-invalid-chars",
|
||||||
@@ -2200,8 +2199,8 @@ const RenderFileUpload = (field) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// block characters < > : " / \ | ? *
|
// block characters < > " / \ | ? *
|
||||||
if (/[<>:"/\\|?*]/.test(name)) {
|
if (/[<>"/\\|?*]/.test(name)) {
|
||||||
return {
|
return {
|
||||||
code: "filename-invalid-chars",
|
code: "filename-invalid-chars",
|
||||||
message: `${name} ${t(
|
message: `${name} ${t(
|
||||||
|
|||||||
@@ -11,14 +11,31 @@ import { fileTypeFromBuffer } from "file-type";
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
|
const FILENAME_ALLOWED = /^[A-Za-z0-9 ._\-:()]+$/;
|
||||||
|
|
||||||
|
function validateFilenameServer(originalFilename) {
|
||||||
|
const name = path.basename(originalFilename || "");
|
||||||
|
|
||||||
|
if (!name) return { ok: false, reason: "Empty filename" };
|
||||||
|
|
||||||
|
if (name.includes("#")) return { ok: false, reason: "Filename contains #" };
|
||||||
|
|
||||||
|
if (/[<>"/\\|?*]/.test(name))
|
||||||
|
return { ok: false, reason: "Filename contains reserved characters" };
|
||||||
|
|
||||||
|
if (!FILENAME_ALLOWED.test(name))
|
||||||
|
return { ok: false, reason: "Filename contains invalid characters" };
|
||||||
|
|
||||||
|
if (name === "." || name === "..")
|
||||||
|
return { ok: false, reason: "Invalid filename" };
|
||||||
|
|
||||||
|
return { ok: true, name };
|
||||||
|
}
|
||||||
const ApiProxy = nextConnect();
|
const ApiProxy = nextConnect();
|
||||||
ApiProxy.use(middleware);
|
ApiProxy.use(middleware);
|
||||||
|
|
||||||
ApiProxy.post(async (req, res) => {
|
ApiProxy.post(async (req, res) => {
|
||||||
var checkHash = req.query.hash;
|
var checkHash = req.query.hash;
|
||||||
// console.log(JSON.stringify(req.body));
|
|
||||||
// console.log(JSON.stringify(req.body.appealData));
|
|
||||||
// console.log(req.files);
|
|
||||||
|
|
||||||
const containerID = req.body.containerID[0];
|
const containerID = req.body.containerID[0];
|
||||||
const casefolderID = req.body.casefolderID[0];
|
const casefolderID = req.body.casefolderID[0];
|
||||||
@@ -40,23 +57,21 @@ ApiProxy.post(async (req, res) => {
|
|||||||
var allowedFilesFormData = {};
|
var allowedFilesFormData = {};
|
||||||
var invalidFiles = []; // To store the names of invalid files
|
var invalidFiles = []; // To store the names of invalid files
|
||||||
|
|
||||||
// for (const [fileName, fileDetails] of Object.entries(req.files)) {
|
|
||||||
// if (allowedMimeTypes.includes(fileDetails[0].headers["content-type"])) {
|
|
||||||
// allowedFilesFormData[fileName] = fileDetails.map((file) => ({
|
|
||||||
// fieldName: file.fieldName,
|
|
||||||
// originalFilename: file.originalFilename,
|
|
||||||
// path: file.path,
|
|
||||||
// size: file.size,
|
|
||||||
// headers: file.headers,
|
|
||||||
// contentType: file.headers["content-type"],
|
|
||||||
// }));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
for (const [fileName, fileDetails] of Object.entries(req.files)) {
|
for (const [fileName, fileDetails] of Object.entries(req.files)) {
|
||||||
const file = fileDetails[0];
|
const file = fileDetails[0];
|
||||||
const filePath = file.path;
|
const filePath = file.path;
|
||||||
|
|
||||||
|
// validate ORIGINAL filename from upload
|
||||||
|
const fnCheck = validateFilenameServer(file.originalFilename);
|
||||||
|
|
||||||
|
if (!fnCheck.ok) {
|
||||||
|
console.log(
|
||||||
|
`File ${file.originalFilename} rejected: ${fnCheck.reason}`
|
||||||
|
);
|
||||||
|
invalidFiles.push(`${file.originalFilename} - Invalid filename`);
|
||||||
|
continue; // do not process further
|
||||||
|
}
|
||||||
|
|
||||||
// Check the MIME type from file headers
|
// Check the MIME type from file headers
|
||||||
const fileMimeType = file.headers["content-type"];
|
const fileMimeType = file.headers["content-type"];
|
||||||
if (allowedMimeTypes.includes(fileMimeType)) {
|
if (allowedMimeTypes.includes(fileMimeType)) {
|
||||||
@@ -83,53 +98,27 @@ ApiProxy.post(async (req, res) => {
|
|||||||
`\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\nFile ${fileName} has an invalid MIME type based on its content.\n\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`
|
`\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\nFile ${fileName} has an invalid MIME type based on its content.\n\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`
|
||||||
);
|
);
|
||||||
invalidFiles.push(fileName); // Track invalid file
|
invalidFiles.push(fileName); // Track invalid file
|
||||||
|
|
||||||
// return res
|
|
||||||
// .status(400)
|
|
||||||
// .json({ error: `Invalid file type for ${fileName}` });
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(
|
console.log(
|
||||||
`Error reading file ${fileName} for MIME type validation`,
|
`Error reading file ${fileName} for MIME type validation`,
|
||||||
error
|
error
|
||||||
);
|
);
|
||||||
// return res
|
|
||||||
// .status(500)
|
|
||||||
// .json({ error: "Failed to validate file type" });
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(
|
console.log(
|
||||||
`\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\nFile ${fileName} has an unsupported MIME type: ${fileMimeType}\n\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`
|
`\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\nFile ${fileName} has an unsupported MIME type: ${fileMimeType}\n\n\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`
|
||||||
);
|
);
|
||||||
invalidFiles.push(fileName); // Track invalid file
|
invalidFiles.push(fileName); // Track invalid file
|
||||||
|
|
||||||
// return res.status(400).json({
|
|
||||||
// error: `Unsupported MIME type for ${fileName}`,
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//console.log("allowedFilesFormData: ", allowedFilesFormData);
|
|
||||||
|
|
||||||
// If no valid files are found
|
|
||||||
// if (Object.keys(allowedFilesFormData).length === 0) {
|
|
||||||
// return res.status(400).json({
|
|
||||||
// error: "No valid files found",
|
|
||||||
// invalidFiles: invalidFiles, // Return the list of invalid files
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
invalidFiles = invalidFiles.map((fileName) => {
|
|
||||||
return `${fileName} - Invalid file`;
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await uploadSingleFile(
|
const data = await uploadSingleFile(
|
||||||
allowedFilesFormData,
|
allowedFilesFormData,
|
||||||
containerID,
|
containerID,
|
||||||
casefolderID
|
casefolderID
|
||||||
).then((data) => {
|
);
|
||||||
return res.status(200).json({ data, invalidFiles });
|
|
||||||
});
|
|
||||||
return res.status(200).json({ data, invalidFiles });
|
return res.status(200).json({ data, invalidFiles });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
consoleLogger(error);
|
consoleLogger(error);
|
||||||
|
|||||||
Reference in New Issue
Block a user