fix: HIGH+MEDIUM bugs from full audit - listen error, JWT, upload, mailer, webhook

This commit is contained in:
2026-07-13 03:49:02 +08:00
parent 7c03fe7635
commit 532efb962f
8 changed files with 56 additions and 29 deletions

View File

@@ -24,7 +24,7 @@ function validateMagicBytes(buffer, mime) {
'image/png': () => head[0] === 0x89 && head[1] === 0x50 && head[2] === 0x4E && head[3] === 0x47,
'image/gif': () => head.toString('ascii', 0, 6) === 'GIF89a' || head.toString('ascii', 0, 6) === 'GIF87a',
'image/webp': () => head.toString('ascii', 0, 4) === 'RIFF' && head.toString('ascii', 8, 12) === 'WEBP',
'video/mp4': () => buffer.includes(Buffer.from('ftyp')),
'video/mp4': () => buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70,
'video/webm': () => head[0] === 0x1A && head[1] === 0x45 && head[2] === 0xDF && head[3] === 0xA3,
};
if (!sigs[mime]) return false;
@@ -58,18 +58,22 @@ const upload = multer({
function finalizeUpload(req, res, next) {
if (!req.files || req.files.length === 0) return next();
for (const file of req.files) {
const buf = fs.readFileSync(file.path);
if (!ALLOWED_MIME[file.mimetype]) {
fs.unlinkSync(file.path);
return res.status(400).json({ error: `不支持的文件类型: ${file.mimetype}` });
}
if (!validateMagicBytes(buf, file.mimetype)) {
fs.unlinkSync(file.path);
return res.status(400).json({ error: '文件内容与声明类型不符,可能是恶意文件' });
const filePaths = [];
try {
for (const file of req.files) {
const fd = fs.openSync(file.path, 'r');
const buf = Buffer.alloc(256);
fs.readSync(fd, buf, 0, 256, 0);
fs.closeSync(fd);
filePaths.push(file.path);
if (!ALLOWED_MIME[file.mimetype]) throw new Error(`不支持的文件类型: ${file.mimetype}`);
if (!validateMagicBytes(buf, file.mimetype)) throw new Error('文件内容与声明类型不符,可能是恶意文件');
}
next();
} catch (e) {
for (const fp of filePaths) { try { fs.unlinkSync(fp); } catch {} }
return res.status(400).json({ error: e.message || '文件校验失败' });
}
next();
}
module.exports = { upload, finalizeUpload, validateMagicBytes, UPLOAD_DIR, ALLOWED_MIME };