技术原理与风险范围
归档条目不是普通相对路径
旧逻辑把 tar 头部的 Name 直接与目标目录连接。归档条目可以包含 ../、反斜杠、绝对路径或 Windows 驱动器前缀;只按当前平台的一种写法检查,很容易让另一种语义穿过边界。[1][6]
校验顺序决定边界是否稳定
官方修复先把目标目录转换为绝对路径,再将条目中的反斜杠统一成正斜杠并清理路径;随后拒绝空名称、父目录、绝对路径和驱动器前缀,最后使用 secure join 将条目约束在目标目录。[6] 这个顺序体现了安全不变量:任何归档名称在落盘前必须解析成目标根目录内的路径。
Windows 语义不能用 Unix 测试替代
../file、反斜杠父目录、盘符与 Unix 绝对路径代表不同类别。补丁回归测试明确覆盖反斜杠、盘符、Unix 绝对路径和嵌套父目录。[6] 跨平台工具必须在测试数据中保留这些差异,不能只在 Linux CI 上验证一种分隔符。
来源可信和解压安全是两道防线
攻击前提包括影响下载归档,意味着制品签名、哈希、TLS 和镜像源准入能降低风险;但解压器仍需防御恶意名称,因为可信源也可能被误配置或供应链污染。安装进程权限越高,目录外写的潜在后果越大。
工程推断:任何在注册、升级或引导阶段解包组件的边缘平台,都应把归档名称、符号链接、文件类型和覆盖策略纳入同一审查。
安全模型与检测思路
以下模型只检查固定路径字符串,不创建归档、不写文件,也不连接 KubeEdge。它演示反斜杠、父目录、绝对路径和盘符的拒绝规则,不等同于完整安全解压器。
import posixpath, re
def safe_entry(name):
normalized = posixpath.normpath(name.replace("\\", "/"))
if not name or normalized in ("", ".."):
return False
if normalized.startswith("/") or normalized.startswith("../"):
return False
if re.match(r"^[A-Za-z]:", normalized):
return False
return True
assert safe_entry("bin/edgecore.exe")
assert not safe_entry("../outside.txt")
assert not safe_entry(r"..\outside.txt")
assert not safe_entry(r"C:\Temp\outside.txt")
print("4 path checks passed; no files written")
输入或请求 | 期望语义 | 检查重点 |
正常嵌套文件 | 允许 | 保留有效归档结构 |
父目录分量 | 拒绝 | 阻止目录外写 |
Windows 反斜杠 | 拒绝 | 跨平台归一化后再判断 |
驱动器前缀 | 拒绝 | 不能被相对连接掩盖 |
修复与交付建议
P0 升级对应维护分支
运行 1.21 的环境至少升级到 1.21.2,1.22 升到 1.22.2,1.23 升到 1.23.1,或采用官方支持的更新版本。[1][3][4][5] 记录 keadm 与 edgecore 的实际版本,不要只看控制面清单。
P0 控制安装包来源
只允许批准的 KubeEdge 下载源,验证归档来源和完整性;禁止在生产加入流程中使用未知自定义组件包。[1] 企业镜像代理应保留制品摘要和上游映射,但不要把访问令牌写入安装日志。
P1 降低安装权限与覆盖能力
在满足部署要求的前提下,以最小权限运行安装步骤,限制可写目录并避免复用日常管理员会话。Windows 服务账号、临时目录和组件目录应分别授权。来源校验不能替代目录边界,二者都要验收。
P1 扩充跨平台归档测试
覆盖正斜杠、反斜杠、盘符、绝对路径、嵌套父目录和空名称。断言拒绝发生在创建文件之前,并验证目标目录外哨兵文件保持不变。真实压缩包测试应在隔离临时目录内完成。
总结
安全解压不是一次字符串拼接,而是把外部命名空间映射到本地文件系统。跨平台归一化、根目录约束与制品来源共同决定边界。本文未确认在野利用,也不把目录外写自动等同于系统接管。