文件内容校验需基于原始字节解析而非扩展名或MIME类型:Excel校验ZIP结构与Sheet数据,PDF校验%PDF-头及交叉引用表,图片校验头信息;同时过滤宏、JavaScript等危险结构,并通过前端计算哈希、后端二次验证确保一致性。

文件内容校验不能只靠扩展名或 MIME 类型,因为这两者都极易被伪造。真正安全的做法是读取文件原始字节,在前端解析并验证其实际结构是否符合预期——比如 Excel 文件必须有合法的 ZIP 容器和 XL 目录结构,PDF 必须以 %PDF- 开头且包含有效交叉引用表。
读取二进制内容做格式解析
使用 FileReader.readAsArrayBuffer() 获取原始字节,再交给对应解析库处理:
- Excel(.xls/.xlsx):用 xlsx 库读取 ArrayBuffer,检查
workbook.SheetNames.length > 0且首 Sheet 至少有一行数据 - PDF:用 pdfjs-dist 的
getDocument()加载,捕获解析异常;或简单校验前 1024 字节是否含%PDF-1. - 图片(JPG/PNG):可用 jpeg-js 或 pngjs 解码头部,确认宽高 > 0、无损坏标记
限制可执行内容与危险结构
即使格式合法,也要过滤嵌入式风险:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- Excel 中禁用宏(
workbook.Workbook.Props.CodeName === undefined)、拒绝含vbaProject.bin的 xlsx - PDF 禁止 JavaScript(检查
catalog.JavaScript是否存在)、禁用富媒体对象(RichMedia) - 图片拒绝含 ICC 配置文件或 EXIF GPS 数据(可选,视业务敏感度而定)
配合后端做一致性哈希校验
前端计算文件内容哈希(如 SHA-256),和服务端上传后重新计算比对:
立即学习“前端免费学习笔记(深入)”;
- 避免中间篡改:上传前用 crypto-js 或原生 SubtleCrypto 计算哈希
- 传给后端时作为请求参数(如
fileHash),服务端收到后立即重算并校验 - 不依赖前端传输的哈希值本身,而是用它触发服务端二次验证动作
内容校验不是“多一道保险”,而是把信任边界从“用户声称是什么”拉回到“文件实际是什么”。前端做解析虽不能替代后端,但能提前拦截 90% 的格式欺骗和无效上传,大幅降低服务端压力与攻击面。

















