[Bug 报告] LAN 部署下审批可被旁路:/api/respond 不在 loopback 钉扎名单,局域网设备可批准工具调用/回答问题
#950
truelove-dreamer
started this conversation in
General
Replies: 0 comments
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.
摘要
Web 部署的
/api面有一份"钉扎到 loopback"的特权方法名单PRIVILEGED_METHODS(dsh-client-connection/lib/index.js:504-520,含 settings/credentials 等敏感方法)。但审批应答方法respond不在名单里。一旦用户通过--trusted-host <LAN-IP>让 LAN 设备可以访问 Web(这是官方支持的用法),任何局域网设备都可以:/api/events.mux),被动拿到approval/requested帧(内含rpcId/approvalId/sessionId);/api/respondPOST 一个伪造的应答包,把outcome置为"allowed-once";ask_user_question。配套问题:Typert 网关以
authority: "trusted-host"注册拦截器(dsh-api-gateway/lib/index.js:62),绕开PRIVILEGED_METHODS的 loopback 复检(dsh-client-connection/lib/index.js:232-240只在 loopback 时用空信任列表)——两套调度平面的安全策略不一致;0.0.0.0绑定还会把全部 LAN IPv4 自动加入信任列表(dsh-web-app/lib/index.js:47-53)。代码注释自己也声明 trustedHosts "explicitly not authentication"。证据(代码与行号)
dsh-client-connection/lib/index.js:504-520(PRIVILEGED_METHODS集合成员列表);dsh-host-apiproxy/lib/index.js:3816-3865(respond(message)→pendingApprovals.get(message.rpcId)→ 校验parsed.data.approvalId !== approval.approvalId || parsed.data.sessionId !== approval.sessionId→approval.resolve(parsed.data.outcome);问题同理:3831-3864);dsh-host-apiproxy/lib/index.js:1350-1361(requestedFrame携带 rpcId/sessionId/approvalId);dsh-client-connection/lib/index.js:569-573(isTrustedApiRequest,Host=LAN IP 字面量命中 trustedHosts 即通过);dsh-host-apiproxy/lib/types/api/approvals.schema.js:11-15({sessionId, approvalId, outcome: "allowed-once" | "rejected"});问题应答dsh-host-apiproxy/lib/types/api/questions.schema.js:17+。复现步骤(概念验证)
前置:
dsh --profile web --trusted-host 192.168.1.100(或自定义 cordis.yml 配host: 0.0.0.0),使 LAN 上其他设备能访问http://192.168.1.100:3080/。ask_user_question);ws://192.168.1.100:3080/api/events.mux(浏览器形态请求,Host 头为 LAN IP 字面量 → 通过栅栏),等待并记录approval/requested帧中的rpcId、approvalId、sessionId;/api/respond(respond的 wire 形态为 client-response 信封):{ "type": "client-response", "rpcId": "<步骤2捕获的 rpcId>", "result": { "ok": true, "value": { "sessionId": "<步骤2捕获>", "approvalId": "<步骤2捕获>", "outcome": "allowed-once" } } }影响
ask_user_question的答案也可被伪造,模型会把它当作真人输入执行后续动作;--trusted-host,若自定义配置把 webserver 绑到0.0.0.0,resolveLanTrust会把所有非内网 IPv4 自动加入信任列表,问题面进一步扩大。建议修复(供讨论)
respond(以及session.export等无认证副作用端点)纳入PRIVILEGED_METHODS,钉扎到 loopback;PRIVILEGED_METHODS门禁(或在 gateway 层单独复检);0.0.0.0,或在 0.0.0.0 时强制要求显式--trusted-host并输出警告;附注
isTrustedApiRequest)本身逻辑正确;All reactions