← 返回工具指南
工具指南文件类型检测Magic NumberMIME文件签名文件上传安全

文件后缀不可信:用 Magic Number、MIME 和文件头判断真实格式

为什么把 .exe 改成 .jpg 不会变成图片?本文说明扩展名、MIME、Magic Number 与文本结构的区别,并给出上传校验和可疑文件排查流程。

打开配套工具 →

同事发来一个 report.pdf,系统却说文件格式不支持;用户上传 avatar.jpg,图片库又无法解码。遇到这种情况,很多人的第一反应是继续改后缀。后缀改得再像,也不会改变文件内部的字节。

文件真实类型检测工具会把文件名扩展、浏览器提供的 MIME 和内容检测结果放在一起,并显示开头 64 字节。这样做不是为了给文件盖一个“绝对真实”的章,而是把三个不同来源的判断分开,尽快找到冲突发生在哪一层。

扩展名、MIME 和文件签名不是一回事

扩展名是给人和软件看的名字

.jpg.pdf.xlsx 都是文件名的一部分。操作系统用它选择默认程序,网站也常用它做第一轮筛选,但用户可以随时改名。

把:

text已剪下 ✓
invoice.exe

改为:

text已剪下 ✓
invoice.jpg

只改变目录中记录的名字。文件里的可执行代码、节区和入口点仍然存在。

扩展名仍然有价值。它表达交付者希望文件怎样被使用,也影响浏览器、服务器和桌面软件的默认处理。但它只能算声明,不能算内容证明。

MIME 描述传输或软件判断的媒体类型

网页上传时,浏览器会给 File.type 一个值;HTTP 响应则通过 Content-Type 告诉浏览器内容类型。标准媒体类型由 IANA Media Types维护,例如:

text已剪下 ✓
image/png
application/pdf
text/calendar

问题在于 MIME 也有来源。浏览器经常根据操作系统映射或扩展名填写 File.type,服务器的 Content-Type 可能来自配置表,甚至被统一写成 application/octet-stream。它比后缀更结构化,却不一定检查了文件内容。

Magic Number 来自内容中的特征字节

许多二进制格式在固定位置有特征字节,常被称为 Magic Number 或文件签名。例如:

格式常见开头
PNG89 50 4E 47 0D 0A 1A 0A
JPEGFF D8 FF
PDFASCII %PDF-
ZIP50 4B 03 04
GZIP1F 8B

成熟检测器不会只比较四个字节。MP4、Office、字体、音视频容器等格式可能需要看品牌字段、容器目录或文件中其他位置。本站工具使用内容检测库处理常见二进制格式,并在未命中时再尝试文本结构。

为什么文本格式更难判断

JSON、CSV、Markdown 和普通 TXT 通常没有独占签名。下面内容既可能是纯文本,也可能被业务系统当作 CSV:

text已剪下 ✓
name,price
apple,12
orange,8

检测器只能根据编码、分隔符与行结构推断。JSON 可以尝试真正解析;ICS 可查看是否以 BEGIN:VCALENDAR 开始;SVG 可以检查 XML 中的 <svg> 根元素。即使如此,损坏的 JSON 可能只能退回“普通文本”,一行带逗号的笔记也可能看起来像 CSV。

所以结果中“二进制签名”和“文本结构”要分开理解。后者适合排查,不适合做唯一访问控制。

ZIP 为什么会变成 DOCX、XLSX 或 APK

不少现代格式本质上是 ZIP 容器:

只看 50 4B 03 04 最多能确认“像 ZIP”,不能确认具体业务格式。进一步识别要查看容器内的目录、manifest、Content Types 或约定文件。

反过来,同一个 ZIP 即使能被识别为 DOCX,也不代表 Word 一定能完整打开。中心目录损坏、必需文件缺失、宏或嵌入对象仍需要对应应用检查。

类型一致不等于安全

文件签名检测不是杀毒软件。下面这些情况都可能通过基础格式识别:

签名的用途是回答“它更像什么格式”,不是“它是否可信”。陌生可执行文件不要运行;需要对外开放上传的系统,还应做大小限制、解码重写、隔离存储、病毒扫描和下载响应策略。

网站上传应该怎样校验

只在前端写:

html已剪下 ✓
<input type="file" accept="image/png,image/jpeg">

只能改善选择体验,不能形成安全边界。用户可以绕过网页直接发请求。

比较稳妥的流程是:

  1. 前端用 accept 提示允许格式,并在本地给出即时错误;
  2. 服务端限制请求体、文件数量和单文件大小;
  3. 生成服务器自己的随机文件名,不信任原始路径;
  4. 同时记录原始扩展、客户端 MIME 与内容检测结果;
  5. 用目标解析器真正解码,例如图片服务读取像素并重新编码;
  6. 高风险格式进入隔离扫描,不直接放到可执行或公开目录;
  7. 下载时设置明确 Content-TypeContent-Disposition
  8. 日志保留检测冲突,方便追查误报和攻击尝试。

图片“解码后重新编码”比简单复制原文件更可靠,因为它会丢掉许多非图像附加内容。不过动画、EXIF、ICC 色彩配置和透明度可能随重编码改变,需要按业务要求保留。

一次实用的排查顺序

先把有问题的文件放入检测工具,观察三列:

  1. 文件名扩展;
  2. 浏览器 MIME;
  3. 内容检测扩展与 MIME。

三者一致但应用打不开,问题更可能在文件损坏、版本、加密或应用兼容。扩展与内容不一致,先确认是不是下载接口命名错误;浏览器 MIME 与内容不一致,则检查操作系统映射和上传端是否只信了 File.type

再查看文件头 HEX。它适合与协议文档、服务器日志或另一个正常样本对比,但不要靠背几个签名手工鉴定所有格式。

最后计算文件 Hash,确认传输前后是否发生变化。类型检测回答“像什么”,Hash 回答“两个字节序列是否相同”,两者解决的问题不同。

文件格式判断没有一个万能字段。真正稳定的做法,是保留每层信息,让扩展名、MIME、内容签名和实际解析结果互相校验。