素材包上传后自动解压到 uploads/2026/11,解压完发现目录里多了个指向 /etc 的软链接,后续读取缩略图时把系统文件也带了出来。日志里能对上时间点,这种反而好排。
zip 条目可以标记成符号链接,解压库按条目内容创建链接,目标路径完全由压缩包决定。解压过程没有检查条目类型,也没有限制链接指向,解压目录就成了跳板。这一点先确认清楚,后面就不用反复试。
for info in zf.infolist():
mode = info.external_attr >> 16
if stat.S_ISLNK(mode):
continue
围绕「zip 软链接解压」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
处理上按这个顺序:解压前遍历条目 跳过符号链接和硬链接;每条目的目标路径做 realpath 校验 必须在解压根目录内;限制单包条目数和解压后总大小 防压缩炸弹;解压放在低权限账户下跑 目录只给它自己。
结果对不对很好判断,带软链接的包再传一次 解压目录里没有链接文件 缩略图接口读不到 /etc 下的内容。
