Skip to content

路径边界:18 处同模式脆弱检查

证据等级:F(源码直接证明)
分析基线:4f843556


一句话

代码库中 18 处 str(path).startswith(str(base)) 调用使用了相同的脆弱模式——缺少路径分隔符检查,允许同级前缀绕过(如 abc123/abc123-evil/ 绕过)。没有共享的路径安全抽象。


1. 模式

str(path).startswith(str(base))

这个模式在以下场景中失效:

  • base = "/workspace/abc123/", path = "/workspace/abc123-evil/etc/passwd"
  • startswith 返回 True——因为 abc123-evil 确实以 abc123 开头
  • 用户/Agent 可以访问 abc123-evil 下的文件,即使不应该

正确的做法是在比较时附加路径分隔符:

str(path).startswith(str(base) + os.sep)

2. 分布

18 处出现在以下模块:

模块 用途
storage_runtime/local.py 本地文件读写
storage_runtime/facade.py 存储门面
sandbox/config.py 沙箱路径配置
agent_tools.py 工具执行的文件操作
email_service.py 邮件附件路径

最危险的场景:email_service.pysend_email 的本地回退路径——零路径验证,可直接访问任意文件作为附件发送。


3. 无共享抽象

18 处调用是独立的复制粘贴,没有封装成统一的路径安全函数(如 is_path_within_base(path, base))。

这意味着:

  • 修复需要逐处修改,容易遗漏
  • 没有单元测试覆盖这个安全属性
  • 新增代码可能继续使用同样的脆弱模式

4. 与 AI Coding 的关系

  1. 复制粘贴模式:AI 在多个任务中独立生成相同的路径检查代码,每次都用 startswith,因为这是"最自然的写法"
  2. 无抽象意识:AI 不会主动说"这个模式出现了 18 次,应该提取为公共函数"——这需要架构师的整体判断
  3. 安全感知缺失startswith 在字符串操作的语义上是正确的——AI 没有意识到路径分隔符在安全语义上的重要性