Node.js中如何校验表单上传的文件是否为真实图片类型?
Node.js服务端校验上传文件为真实图片的方案
核心校验逻辑不依赖可伪造的文件扩展名、请求头Content-Type,而是校验图片的魔数(文件头固定标识),不同格式的图片前几个字节是固定的,修改扩展名不会改变文件本身的头部内容,是目前最可靠的基础校验手段。
方案一:手写轻量校验逻辑
适合仅需要支持常见图片格式的场景,自己维护魔数列表即可:
// 定义允许的图片格式对应的魔数(16进制头部标识) const ALLOWED_IMAGE_MAGIC = { jpg: 'ffd8ff', png: '89504e47', gif: '47494638', webp: '52494646' } // 校验函数:传入文件的Buffer对象 function isRealImage(fileBuffer) { // 取前4个字节足够覆盖常见图片的魔数长度 const fileHeader = fileBuffer.slice(0, 4).toString('hex').toLowerCase(); return Object.values(ALLOWED_IMAGE_MAGIC).some(magic => fileHeader.startsWith(magic)); } // 路由中使用 routerProgress.post("/home/upload-progress", (req, res) => { const front = req.files.front; const from_side = req.files.from_side; const backwards = req.files.backwards; // 批量校验所有上传文件 const allValid = [front, from_side, backwards].every(file => { // 先判断文件存在,再校验文件头 return file && file.data && isRealImage(file.data); }); if (!allValid) { return res.status(400).send({msg: '所有上传文件必须为有效图片,禁止修改扩展名伪造上传'}); } // 后续正常业务逻辑 })
注:如果你使用multer作为文件上传中间件,文件的Buffer属性为
file.buffer,对应替换代码中的file.data即可。
方案二:使用成熟npm包校验
如果需要支持更多图片格式、不想自己维护魔数列表,可以用专门的文件类型校验npm包,这类包底层同样基于魔数校验,还会额外做格式完整性校验,避免仅修改了文件头的恶意文件绕过。
安装依赖的命令:npm install file-type
使用示例:
const { fileTypeFromBuffer } = require('file-type'); async function isRealImage(fileBuffer) { const typeResult = await fileTypeFromBuffer(fileBuffer); // 校验返回的mime类型是否为图片大类 return typeResult && typeResult.mime.startsWith('image/'); } // 路由需添加async支持异步逻辑 routerProgress.post("/home/upload-progress", async (req, res) => { const front = req.files.front; const from_side = req.files.from_side; const backwards = req.files.backwards; try { const validResults = await Promise.all([front, from_side, backwards].map(async file => { return file && file.data && await isRealImage(file.data); })); if (!validResults.every(Boolean)) { return res.status(400).send({msg: '上传文件包含非图片内容,请检查后重新上传'}); } // 后续正常业务逻辑 } catch (err) { return res.status(500).send({msg: '文件校验失败,请稍后重试'}); } })
额外注意事项
- 前端设置的
accept="image/*"仅用于优化用户选择体验,完全可以通过抓包修改等方式绕过,服务端校验是唯一可靠的校验手段 - 如果你有更高的安全要求,可以额外引入图片处理库(如sharp)对上传文件尝试解码,能正常解码输出才判定为有效图片,可彻底规避仅修改文件头的特殊构造恶意文件
- 生产环境建议同时限制上传文件的大小,避免大文件攻击
内容的提问来源于stack exchange,提问作者Gonsa02
相关产品推荐
相关产品推荐

