文件上传校验变量一致性
TOPIC SOURCE
为文件上传功能做威胁建模:从信任边界到可回归的安全测试
文件上传接口即使做了类型校验,也可能把不该接收的文件写入存储。关键不只是“有没有校验”,而是校验对象与最终写入对象是否一致:若检查的是客户端提交的源文件名,落盘却使用另一个可由客户端指定的目标文件名,检查通过并不能证明最终路径和扩展名安全。
代码评审应沿着一次上传追踪变量流向:服务端从哪里取得文件内容、源文件名和目标文件名;类型判断读取了哪个值;写入操作又使用了哪个值。尤其要核对中途是否发生重命名、拼接路径或覆盖变量。只要决定落盘结果的值在校验后仍可被不可信输入改变,前面的判断就没有约束住写入行为。请求中的文件名和类型声明都来自客户端,不能因其通过前端检查就视为可信。
更稳妥的设计是由服务端决定最终文件名和存储位置,并对实际将被保存的文件执行相应校验。文件内容、允许的类型与最终扩展名应相互匹配;客户端提供的目标文件名参数不应单独决定路径或扩展名。存储目录是否允许脚本解析也需要独立检查,不能让类型校验承担全部防护责任。
回归测试应专门覆盖“源文件看似合法、目标文件名不合法”的组合,同时检查响应和实际存储结果:请求被拒绝,或目标名称被安全替换后,危险扩展名与非预期路径都不应出现。再用合法文件确认正常上传未受影响。这样验证的不是某个校验函数是否被调用,而是被校验的对象是否始终与最终保存的对象一致。

参与讨论
校验过的文件名和落盘用的不是同一个,确实容易漏看