星巡研究院
公开阅读
Web 安全
2026年11月9日

文件上传绕过为什么总在“解析”层

后缀白名单、MIME 校验、内容检查,三样都做了,上传点还是被打穿。原因不在校验写得糙:三道检查全在"进门"环节,而决定成败的是"文件落地之后,谁来解析它"。

三道检查都做了,为什么还失守

一条常见的上传链路:扩展名白名单只放图片与文档、Content-Type 做比对、图片走二次渲染、落地文件名换成随机串、目录放在 Web 根下。

每一步都合理。审计报告指出的位置却不在这些代码里,而在同一条链的另一端:落地目录能不能执行脚本、有没有别的地方会把这个文件当代码读。

上传点的风险从来不是单点,是两段拼起来——落地位与执行位。校验只管落地位,执行位常常写在别的配置文件里。

三检各自的边界

检查判定对象能否阻止落地后被当代码执行
扩展名白名单文件名的字符串否。名字是给人看的,解析器认的是另一套规则
MIME 校验请求头里的声明否。声明由客户端给出,服务端只能验证它像不像
内容/魔数检查文件的字节特征否。判定的是"这文件像什么",不是"谁会执行它"

三行都写着"否",原因同一个:三检判定的都是"文件的属性",而执行与否取决于"解析环境"。

一段代码是不是脚本,不由它的后缀决定,由处理它的那个进程决定。这是上传问题与 SQL 注入最像的地方——判据都在上游,结论却在下游。

解析层的三种放大

一、目录可执行。 落地目录在 Web 根内,且该目录允许脚本执行。此时"能写文件"直接等于"能写可执行文件",中间不需要任何绕过。反过来,目录禁执行时,即使传上去一个标准脚本文件,访问它也只是拿到源代码。

二、解析器取值与校验侧不一致。 校验侧取最后一个后缀或白名单里的第一个,解析侧按自己的顺序取。Apache 的多后缀映射、Nginx location 正则的匹配顺序、php-fpm 的扩展名限制,都可能与校验侧得出不同结论。同一个文件名,两套判定,谁在前面谁说了算。还有一类解析器干脆不看后缀,按内容嗅探决定是否交给脚本处理器;后缀白名单在这类解析器面前直接失效。

三、包含点与重写规则。 上传文件被 include、被模板引擎当成缓存、被伪静态规则转给脚本处理——静态文件在某一刻被当成代码读入。这一步不需要目录可执行,只需要一个"读它的人"。

三种放大里,第一种是配置问题,第二种是判定不一致,第三种是把数据当代码。危害都在解析环节,都不在上传接口的代码里。

组合链

一条完整的链需要两个位置:能落地的上传点、能执行或能读入的位置。缺一个都不成链。

这也解释了很多争议:单看上传接口,白名单齐全,判不了;单看某一个目录配置,也没人往里写文件,判不了。两个位置接上,才是漏洞。

判据可以借用漏洞判定五问法的前两问——先问"能不能多做一步无权操作",再看"这一步离业务目标有多远"。上传点给出的是"多一步写文件",执行位决定"能不能再往前走"。

审计怎么看

按顺序看四件事。

一、落地目录与 Web 根的关系。 取真实路径比较,不看配置里写的相对路径。目录在 Web 根内、且可执行,后面两条才有意义。

二、目录的解析配置。 目录级是否关掉脚本解析、扩展名是否被全局映射到脚本处理器、location 的匹配顺序。这一层通常不在代码仓库里,要去看部署配置。

三、有没有"读它的人"。 全文搜 include、require、模板加载、缓存读取,看路径是否可受外部影响。有包含点,上传目录就不只是存储。

四、重写与伪静态。 规则会不会把静态后缀交给脚本进程。规则写错一次,后面所有上传点都变成入口。

这套找法在站内《危险函数检索为什么在真实项目里失效》里已经拆过一遍:搜函数名找不到缺陷,因为缺陷长在位置关系上,不长在函数调用上。站内文章:危险函数检索为什么在真实项目里失效

怎么修

四件事,按代价从低到高。

文件名由服务端决定。 随机重命名,扩展名按内容映射生成,不采信客户端给的名字。这一条消掉"名字与解析不一致"的大半问题。

落地目录禁执行。 目录级关闭脚本解析,或把目录移出 Web 根,只通过下载接口输出。这是最有效的一条,因为它从根上取消了"执行位"。

双白名单。 内容类型白名单加扩展名白名单,两者都要过;扩展名与处理器之间用固定映射表,不做字符串拼接。

物理分离。 上传目录与站点目录分开,必要时放在独立域名或对象存储下,下载走鉴权接口,不让浏览器直连原始文件。

四件事里,只做第一件是缓解,做了第二件才算修复。

上传点的价值不在"传上去",在"传上去之后有没有人执行它"。 按这句话验收:改完之后,每一个上传目录都应该能回答"谁在解析它、用什么规则解析"。

本文仅用于安全学习与授权环境下的测试。文中所有示例均为本地或授权靶场环境,不构成对任何真实系统的测试指引。

仅限授权测试,严禁非法滥用。

#文件上传#解析器#绕过

读到这里,说明你在认真看。加入社群,与我们一起深挖底层。

或点此直接进入「星巡底层研习」 →
星巡底层研习知识星球二维码

扫码加入交流社群