路径边界:18 处同模式脆弱检查¶
证据等级:F(源码直接证明)
分析基线:4f843556
一句话¶
代码库中 18 处 str(path).startswith(str(base)) 调用使用了相同的脆弱模式——缺少路径分隔符检查,允许同级前缀绕过(如 abc123/ 被 abc123-evil/ 绕过)。没有共享的路径安全抽象。
1. 模式¶
这个模式在以下场景中失效:
base = "/workspace/abc123/",path = "/workspace/abc123-evil/etc/passwd"startswith返回True——因为abc123-evil确实以abc123开头- 用户/Agent 可以访问
abc123-evil下的文件,即使不应该
正确的做法是在比较时附加路径分隔符:
2. 分布¶
18 处出现在以下模块:
| 模块 | 用途 |
|---|---|
storage_runtime/local.py |
本地文件读写 |
storage_runtime/facade.py |
存储门面 |
sandbox/config.py |
沙箱路径配置 |
agent_tools.py |
工具执行的文件操作 |
email_service.py |
邮件附件路径 |
最危险的场景:email_service.py 中 send_email 的本地回退路径——零路径验证,可直接访问任意文件作为附件发送。
3. 无共享抽象¶
18 处调用是独立的复制粘贴,没有封装成统一的路径安全函数(如 is_path_within_base(path, base))。
这意味着:
- 修复需要逐处修改,容易遗漏
- 没有单元测试覆盖这个安全属性
- 新增代码可能继续使用同样的脆弱模式
4. 与 AI Coding 的关系¶
- 复制粘贴模式:AI 在多个任务中独立生成相同的路径检查代码,每次都用
startswith,因为这是"最自然的写法" - 无抽象意识:AI 不会主动说"这个模式出现了 18 次,应该提取为公共函数"——这需要架构师的整体判断
- 安全感知缺失:
startswith在字符串操作的语义上是正确的——AI 没有意识到路径分隔符在安全语义上的重要性