# 威胁模型(v0) > 与 [`01-mvp-scope.md`](01-mvp-scope.md) 配套。技术名词保留英文。 > 文档示例一律使用 `example.com` / `127.0.0.1` / `YOUR_TOKEN` 占位,不得写入真实 token、私钥或内网主机名。 ## 资产 | 资产 | 说明 | | --- | --- | | `deviceToken` | 配对后手机持有的长期秘密。服务端只存 SHA-256 哈希。 | | 服务端 X25519 私钥 | 数据面 E2EE 的身份锚。文件 0600,目录 0700。 | | 会话内容 | Agent 输出、用户短回复、当前会话元数据。经 E2EE 后对中继/旁路不可读。 | | 审批决策 | 批准 / 拒绝 / 提问应答。写操作必须可归因到 `deviceId`。 | ## 攻击者 | 攻击者 | 能力假设 | | --- | --- | | LAN 被动嗅探 | 可读同网段明文 HTTP / WS。 | | LAN 主动 MITM | 可 ARP/DNS 欺骗,在页面加载时注入或替换 JS。 | | QR 泄露 | 拍照、截图、投屏使 pairing offer 离开操作者控制。 | | 手机丢失 | 已配对设备落入他人之手,直到吊销。 | | 恶意插件 | 与本插件同住一个 DSH profile,可读部分宿主服务。 | | 自建中继运营者 | 控制 Worker 源码与 Cloudflare 账号;可见连接元数据;PIN 路径可见 offer。 | ## 安全不变量 1. **未认证连接只处理握手。** 数据面在完成配对握手之前,不接受任何业务 RPC、不返回会话内容。 2. **秘密落地约束。** `deviceToken` 只存 SHA-256 哈希;私钥、注册表、审计文件权限 0600(所在目录 0700);密钥永不进入日志、截图或仓库。 3. **RPC 白名单默认拒绝。** 未知方法一律拒绝。写操作(审批、提问应答、短回复)写入审计记录,可归因到 `deviceId`。 4. **管理面 owner 围栏。** 管理面始终只绑回环。本机/SSH 必须是 loopback TCP peer 与匹配的 loopback Host/Origin;HTTPS 反代还必须同时满足精确 peer allowlist、精确 HTTPS Origin/Host、代理鉴权后注入的 owner proof、`Sec-Fetch-Site: same-origin` 与独立 mutation CSRF proof。非受信 peer 的 `X-Forwarded-*` 一律忽略,配置不完整 fail closed。 5. **不触碰宿主围栏。** 不修改、不削弱 `dsh web` `/api` 的绑定与鉴权;不抢 `api-proxy` 的审批 / 提问 provider。 6. **文档占位。** 一切公开示例使用 `example.com` / `127.0.0.1` / `YOUR_TOKEN`,不出现真实地址或凭据。 ## 诚实边界(v0) 手机页经 **LAN HTTP 明文下发**。主动 LAN MITM 可在页面加载时注入恶意 JS;页面一旦被替换,后续 E2EE 只保护「恶意脚本与服务器之间」的信道,管不到投递层。 这是**浏览器客户端相对签名原生 App 的固有差距**,不是本里程碑的实现疏漏。`/m` 响应附带 CSP(`script-src 'self'`、`frame-ancestors 'none'`)与 `X-Frame-Options: DENY`,用来收窄**已合法下发页面**被注入后的能力;它**不能**阻止首次 HTTP 被替换。 缓解(按优先级): - 推荐把数据面放在 Tailscale / WireGuard 等加密 overlay 内,而不是裸 LAN。 - **Cloudflare Quick Tunnel(方案 1,本里程碑)**,设置页显式开启,只暴露数据面: - **`/m` 会公开可达**:任何人持有 `https://<随机>.trycloudflare.com` 即可加载手机页。TLS 在 Cloudflare 边缘终结,回源 `http://127.0.0.1:6879`。 - **配对仍是 fragment + E2EE**:`/m` 静态页面本身不含会话秘密;没有 fragment 令牌(+ 共享密钥)仍不能完成 `e2ee_auth`。URL 等同临时钥匙,勿转发。 - **必须随 unload /「停止」杀掉 `cloudflared` 子进程**(`ctx.effect` disposer)。 - **禁止**把 `3080` / `dsh web` 送进隧道;隧道 `--url` 只指向 `127.0.0.1:<数据面端口>`。 - M4 可选:自签 HTTPS + 二维码钉死证书哈希(TOFU)。 - 未来选项:路线 C 原生 App,用签名包投递客户端,彻底离开「首次 HTTP 下发」模型。 - **方案 2:自建会合中继(M5)**,设置页显式开启,桌面与手机各自出站连操作者自己的 Worker: - **不**把本机 `6879` / `3080` 打到公网;中继只做会合与密文转发。 - **投递层是边缘 TLS**:裸 LAN MITM 换不了 `/m`。被攻破的 Worker 仍可下发恶意 JS——自建 = 信任该 CF 账号与该源码。 - **QR fragment 不到 Worker**;PIN 兑换(`POST /m/claim`)会让 Worker 运营者在 TTL 内看见完整 offer(含 `deviceToken`)。 - Worker 可见连接元数据(谁在连、帧长/时间),不可见 `e2ee_auth` 之后的 RPC 明文。 - **禁止**把 `3080` / `dsh web` 接到 Worker;**禁止**本仓库运营公共会合点。 - 规格见 [`05-cloud-relay.md`](05-cloud-relay.md)。 **明确出界(v0 不防、不声称防):** - 桌面被控(攻击者已在跑 `dsh web` 的机器上) - 浏览器扩展窃取设置页 / 配对码 - 通用 XSS(宿主或其它插件的 DOM 注入) - 手机页把 X25519 私钥与 resume offer 放在 `sessionStorage`(非 `localStorage`):关标签即失效,降低共享设备上的残留;仍无法抵御同页 XSS 读存储 ## 禁止事项 / Prohibitions 以下文案可直接展示给用户(中英对照)。 - **不共享他人凭据。** Do not share another person's credentials. - **不监测未授权账户。** Do not monitor accounts you are not authorized to access. - **不裸暴露公网端口。** Do not bind the data-plane port on `0.0.0.0` to the public Internet. A user-started Cloudflare Quick Tunnel (HTTPS at the edge, localhost origin) or a **self-hosted** rendezvous Worker (desktop outbound only) is an explicit exception; never tunnel `3080`. - **不暗示 DeepSeek 官方背书。** This plugin is not affiliated with, and is not endorsed by, DeepSeek. 错误示例(禁止照抄到生产):`ws://203.0.113.10:6879?token=s3cret` 正确示例:`ws://127.0.0.1:6879` 或 `wss://example.com`,token 写作 `YOUR_TOKEN`。