核心风险是路径遍历破坏租户隔离,必须校验每个zip条目归一化路径是否严格落在目标租户目录内,拦截含../、绝对路径、空字节等危险结构,并结合进程降权、目录acl与运行时隔离加固。

在多租户环境中解压 ZIP 文件,核心风险不是 ZIP 本身“越权”,而是解压过程可能意外创建跨用户目录、覆盖他人文件、或释放含 ../ 的恶意路径文件(即路径遍历),从而打破租户隔离。关键不在 ZIP 包的权限位,而在解压行为是否受控。
严格校验 ZIP 内部路径,拦截危险结构
ZIP 文件不存储 Unix/Linux 的 rwx 权限,但可包含任意路径字符串。攻击者可构造如 ../../../etc/passwd 或 tenant2/config.json 这类路径。解压前必须做白名单校验:
- 提取每个文件条目的
filename,用标准路径解析函数(如 Python 的os.path.normpath())归一化 - 检查归一化后路径是否以目标租户目录为前缀(例如
/var/tenants/tenant123/),否则直接跳过或报错 - 拒绝含
..、空字节、控制字符或绝对路径(/开头)的条目
解压时强制限定根目录,禁用路径逃逸
不能依赖解压工具默认行为。不同语言需主动设限:
-
Python(zipfile):不用
extractall()直接指定路径,改用extract()+ 手动拼接安全路径;或使用pathlib.Path(target_dir).resolve()确保目标是真实子目录 -
Linux(unzip):必须加
-d /safe/path,且确保该路径属于当前租户;避免不带-d解压到当前目录(当前目录可能不可控) -
PHP(ZipArchive):调用
extractTo()前,先用realpath()验证目标路径,并确认其位于租户专属基目录下
运行时隔离:租户级文件系统视图
光靠应用层校验不够,建议结合系统级防护:
- 为每个租户分配独立的工作目录(如
/mnt/tenant-abc/),并用 Linuxchroot、命名空间(userns/mountns)或容器(Docker)隔离进程视图 - 目标目录设置严格 ACL:仅允许对应租户 UID/GID 读写,禁止其他租户访问(
chmod 750+setfacl) - 解压进程以租户专用低权限用户身份运行(非 root),即使路径校验漏掉,也无法写入他人区域
附加加固:解压后清理与审计
解压完成不是终点:
- 扫描输出目录,检查是否有非预期的符号链接、设备文件或 setuid 文件(这些在 ZIP 中极少合法)
- 对解压出的可执行文件(如脚本、二进制)自动清除执行位(
chmod -x),除非明确白名单放行 - 记录每次解压的租户 ID、ZIP SHA256、文件列表及路径校验结果,便于事后追溯











