dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
A fail-closed security baseline plugin for DeepSeek Harness (DSH): policy-gated network egress, a monotonic subagent permission ceiling, and one hash-chained audit log of every tool decision and result.
DSH 的安全基线闸门:网络出口独立成层,子代理权限只能收窄不能放宽,每一次判定与结果写进同一条可校验的哈希链。
默认行为一句话:公网主机放行;私网、回环、链路本地、CGNAT 与云元数据地址默认阻断。配置 allowedHosts 后转为白名单模式,白名单外的公网目标需审批(strict 下直接拒绝)。
版本0.1.0· DSH peer>=0.2.1-rc.2 = 22.5(node:sqlite;22.13 起无需额外 flag)
Host 半区与客户端均已实现;真机验证范围见验证状态与待验证项:桌面版验证服务端加载、审计、链与 HTTP 路由,CLI Web 验证客户端渲染、主题与 API。
dsh plugin --profile web add dsh-baseline装好后重启 DSH,左侧栏出现「基线审计」即生效。桌面版请在 Plugin Manager 里安装 dsh-baseline。
本包安装即启用。若想先审查再启用,见安装与启用第 3 条。
只使用官方公开的扩展点和事件:tools/pre-execute、tools/result、ctx.tools.guard()、ctx.approval、ctx.agents、webServer.register()、客户端 slots / locale。不依赖未文档化的内部 API,不替换、不补丁、不包装 DSH 自身的运行时文件。
任何不确定的判定、审批缺失、审批超时、子代理 lineage 断裂、审计库不可用,一律拒绝,并给出明确原因。宁可让一次调用失败,也不让它在无法验证时继续执行。
dsh-permgate:互补。它做 8 类权限拦截;本插件不替代权限分类,只守网络、子代理上限、凭据与破坏性操作这几条底线。auditrail:互补。它做 SQLite 哈希链审计;本插件的链只记录自身的判定与结果,不接管全局审计。dsh-plugin-product-subagents:互补。它提供子代理上限;本插件在 ctx.tools.guard() 里再保一次单调上限,任何后注册的 listener 或 guard 都不能把子代理放宽。dsh-plugin-vet:互补。它做运行时观察;本插件做阻断、审批与可校验审计。require('child_process')”的逃逸。纯插件层看不到绕过 ToolRuntime 的原生进程调用,这需要进程级隔离、容器或操作系统策略。run_code 的 worker thread 逃逸。worker 内执行的代码不经过可拦截的工具调用边界,同样需要进程级隔离。127.0.0.1 或发生 DNS rebinding 时,本插件只能看到主机名字符串。启用插件后,以下两类规则无条件、优先于所有自定义规则执行,配置文件和面板都无法关闭:
/dev/sd*、/proc/self/mem、/sys/*、\.\PhysicalDrive*)。网络底线分两部分:
.internal、.svc、.local 等);blockedCIDRs 定义。默认列表覆盖这些范围;删除条目会明确削弱该范围的阻断,这是操作者的显式选择,README 不把它伪装成不可推翻。凭据读取/外发拒绝与子代理权限上限默认开启,只能通过配置文件中的 guard 开关显式关闭,面板不能关闭。
“默认开启”指策略在安装后即生效;本包安装即启用(见安装与启用)。如需先审查再启用,见该节第 3 条。
大多数 Agent 安全产品在“工具名”层面做权限控制。但真实的逃逸往往发生在三个地方:网络出口、子代理继承、以及“谁在什么时候基于什么理由允许了什么”。dsh-baseline 把这三处做成同一套可验证的机制:
层 · 机制 · 不可绕过的原因 网络出口 · 私网/元数据默认阻断、可选主机白名单、按会话出口预算、严格模式逐个审批 · 网络命令与 URL 在 pre-execute 中提取,硬规则在 guard 中二次复核 子代理上限 · 沿 session.header.parentSession 回溯祖先,重放同一次调用的策略 · 在 ctx.tools.guard() 中执行;guard 只有“拒绝/不干预”两种结果,没有 allow,后注册者无法放宽。fork 会话不计入 审计 · 判定与结果写入同一条 SHA-256 哈希链,客户端只读查询 · 写入前脱敏;verifyChain() 返回第一条断链记录;客户端不直接接触 SQLite
它不做的:
dsh-permgate 的权限类别;ctx.approval;localStorage。>=0.2.1-rc.2 <0.3.0(peerDependencies 与 engines.dsh 的区间;见下方兼容矩阵)>= 22.5,且 Node 带 node:sqlite(本包使用 DatabaseSync)。22.13 起无需额外 flag;22.5–22.12 需要以 --experimental-sqlite 启动 DSHwebServer;面板与 HTTP API 依赖它)DSH · Cordis · 状态 0.2.1-rc.3 · 4.x · 已验证(桌面版:加载 / deny / 审批拒绝 / 审计链 / HTTP 路由) 0.2.1-rc.2 · 4.0.5 · 已验证(CLI Web:客户端渲染 / API 全路由)+ 服务端真实 ToolRuntime 集成测试 其它 0.2.x · 4.x · 未验证(peer 与 engines.dsh 允许,但未跑过)
package.json 的 dsh.compatibility.dsh 记录首个完成真机验证的版本(0.2.1-rc.2),不代表只支持该版本;实际允许范围由 peerDependencies['@deepseek-ai/dsh-tools'] 与 engines.dsh 的区间决定。
npm install
npm run build产物:
lib/index.js 与 lib/types/:Host 半区lib/client.js:客户端 bundle(约 60 KB)locale/zh.json、locale/en.json:面板与 Plugin Manager 的显示元数据icon.svg:插件图标dsh-baseline(从 npm),或使用 install_bundle 安装本目录 / npm pack 后的 tarball。不要手工复制 node_modules 或改写 Loader 配置来替代安装步骤。注:已在 DSH 0.2.1-rc.3 desktop 上通过 Plugin Manager 从 npm 安装并验证(侧栏入口、面板、导出、熔断解除均通过)。Security baseline,描述与图标来自 locale/*.json 与 icon.svg。cordis.patch.yml 只做一次 insert,不带 disabled 键:- insert:
- id: dsh-baseline
name: dsh-baseline
config: {}原因:Plugin Manager 的安装开关只会把包写进 dsh.profile.bundles,不会翻转条目的 disabled。早期版本把 disabled: true 写死在包里,结果是「装上了、列表里有、重启后什么都没发生」——插件被合成进树里,却从未实例化。
想先审查再启用,不要改包内文件,而是在 profile 的 cordis.patch.yml 末尾加一行覆盖:
- id: dsh-baseline
disabled: true审查完改成 false 或删掉该行,再重启 DSH。
baseline。面板需要 Host 半区已启用且 webserver/index-inject 已注入启动 token。DSH Loader 中,匹配到同一插件的 config 会整体替换原有配置,而不是逐字段合并。Schemastery 会为缺失字段补默认值,但不会保留你上一次写的值。覆盖配置时,请把需要偏离默认值的字段一次写全。
推荐的最小启用配置:
- insert:
- id: dsh-baseline
name: dsh-baseline
disabled: false
config:
defaultMode: standard行为 · loose · standard(默认) · strict 硬规则(含凭据/网络) · 执行 · 执行 · 执行 自定义规则 · 执行 · 执行 · 执行 内置审批规则 · 不触发 · 触发 · 触发 严格模式兜底 · 不启用 · 不启用 · 启用 无规则命中时的默认 · 允许 · 允许 · 只读放行;网络或可能修改状态的调用需审批 熔断 / 出口预算 / 审计降级 · fail-closed · fail-closed · fail-closed 子代理上限(启用时) · 执行 · 执行 · 执行
standard 是低误报默认:只在有明确信号时弹审批(下载管道执行、破坏性 Git、破坏性 SQL、持久化、监听端口、读 .env、写系统目录、证据不完整,以及配置了白名单后的白名单外目标)。
这些规则在自定义规则之前评估,effect 固定为 deny,risk 为 critical(出口预算的 guard 拒绝为 high)。
guard-private-network 的规则本身不能被配置或面板关闭,但其 IP 段集合来自 blockedCIDRs,删除某个 CIDR 会使其不再命中;始终阻断的内部主机名不受列表影响。凭据类规则受 guard.enforceCredentialDeny 控制。
规则 ID · 触发条件 guard-destructive-command · 递归删除根目录/home(操作数先做 POSIX 规范化,/tmp/..、/./、// 视为根);删除盘符根;format 磁盘;dd 写块设备;mkfs* / wipefs / blkdiscard;对设备 shred;在根目标递归 chmod/chown;在根目标 find -delete/-exec;fork bomb guard-root-write · 任意命令或工具的写入目标规范化后等于文件系统根(/、C:、//)或当前用户主目录(~、$HOME);覆盖 mv x /、> / 等非 rm 变体 guard-device-write · 写 /dev/sd*、/dev/nvme*、/proc/self/mem、/sys/*、.\PhysicalDrive* 等设备或内核接口 guard-credential-read · 读真正的凭据/密钥:~/.ssh/ 下的 id_rsa/id_dsa/id_ecdsa/id_ed25519 与 *.pem/*.key/*.p12/*.pfx/*.jks/*.keystore,以及 .npmrc、.netrc、.pgpass、~/.aws/credentials、~/.azure/、~/.kube/config、~/.docker/config.json、~/.git-credentials、~/.gnupg/、gcloud 凭据、~/.password-store/。~/.ssh/config 仅审批(见 builtin-credential-config-read);known_hosts 与 *.pub 不拒绝 guard-credential-write · 写入任意 ~/.ssh/authorized_keys(持久化后门) guard-credential-exfiltration · 同一次调用既读凭据又访问网络或写私钥;或读取 .env/敏感配置同时访问网络(即使 loose 模式也拒绝) guard-private-network · 目标命中 blockedCIDRs,或命中始终阻断的内部主机名(见网络策略)
凭据三条规则只在 guard.enforceCredentialDeny: true(默认)时执行。其余四条不可关闭。
规则 ID · 触发条件 · standard · strict builtin-pipe-to-shell · 下载内容直接管道给 sh/bash/python/node 等解释器;PowerShell irm \ · iex · 审批 · 审批 builtin-destructive-git · git push --force、reset --hard、clean -f/-x、checkout/restore .、branch -d、stash drop/clear、filter-branch/filter-repo · 审批 · 审批 builtin-destructive-database · DROP TABLE/DATABASE、TRUNCATE TABLE、ALTER TABLE ... DROP、无 WHERE 的 DELETE FROM · 审批 · 审批 builtin-persistence · crontab 写入、systemctl enable、launchctl load、schtasks /create、注册表 Run 自启动、chkconfig --add、update-rc.d,以及写入 shell rc/systemd/cron 等持久化位置;authorized_keys 写入由 guard-credential-write 直接拒绝 · 审批 · 审批 builtin-listener · nc -l、socat ... listen、ssh -R、python -m http.server、php -S、ngrok/cloudflared/chisel/frpc · 审批 · 审批 builtin-sensitive-read · 读取 .env / .env.*(.example、.sample、.template、.dist、.md 除外) · 审批 · 审批 builtin-credential-config-read · 读取 ~/.ssh/config(可能包含 ProxyCommand);known_hosts 与 *.pub 不触发 · 审批 · 审批 builtin-protected-write · 写 /etc、/usr、/bin、/sbin、/boot、/dev、/proc、/sys、/var/lib、/var/spool、/Library、/System、C:\Windows、C:\Program Files 等受保护位置(/dev/null、/dev/stderr、nul 等无害设备目标除外) · 审批 · 审批 builtin-unverifiable-evidence · 参数遍历触顶(truncated)且涉及网络或写入 · 审批 · 拒绝 builtin-network-unverifiable · 配置了 allowedHosts、调用涉及网络、但无法确定目标主机 · 审批 · 拒绝 builtin-network-not-allowed · 配置了 allowedHosts、目标不在白名单中 · 审批 · 拒绝 builtin-egress-budget · 仅严格模式:maxEgressBytes > 0 且检测到上传标志 · — · 审批 builtin-workspace-escape · 仅严格模式:写入工作区之外的绝对路径 · — · 审批
严格模式兜底(没有规则命中时):
default-strict-allow);builtin-strict-network);builtin-strict-mutation);default-allow)。rules:
- id: allow-npm-registry
effect: allow
priority: 100
risk: low
reason: Package installs may reach the npm registry
tools: [bash]
commands: ["npm *", "pnpm *"]
hosts: ["registry.npmjs.org"]匹配语义:
tools 和 hosts,就必须同时满足。hosts 中任意一个命中即可。tools/paths/commands/hosts/agents 之一。tools、agents:大小写不敏感的 glob。agents 匹配 agent.id(会话 ID)。paths:同时按路径 glob 与普通 glob 匹配,覆盖真实路径、词法路径和工作区相对路径;路径模式中 * 不跨 /。commands:默认是“包含”匹配;模式中出现 *、?、[ 时按 glob 匹配。会匹配完整命令与每个解析后的命令段。hosts:主机名 glob 或 CIDR。priority 降序;相同优先级按声明顺序;第一条命中的规则生效。effect 可为 allow / deny / ask,risk 为 low/medium/high/critical。allow 不能放行破坏性命令、设备写入、命中当前 blockedCIDRs 的网段或已启用的凭据拒绝。allow 仍会经过 guard 的子代理上限检查。builtin-、guard-、network-、__ 前缀;每个维度最多 64 个模式。ctx.tools.guard() 的契约是“只返回拒绝原因或不干预”,没有 allow。因此它是唯一能保证“后注册的 listener 不能放宽前人的拒绝”的位置。本插件的 guard 按以下顺序检查:
guard-audit-unavailable);guard-fuse);guard-egress-budget);pre-execute 记录 → 拒绝(guard-policy-bypass,防止绕过判定阶段);guard-subagent-ceiling);deny > ask > allow),拒绝(guard-subagent-ceiling)。lineage 的来源:
session.header.parentSession 向上走;header.origin === 'subagent' 但没有 parentSession → lineage 断裂;ctx.agents.get(parentSession) 找不到父会话 → 断裂;这是“对同一次调用重放祖先策略”的单调上限,不是完整的能力集合格。它保证:如果祖先在同一调用上会被更严格地对待,子代理就不能凭自己的配置获得更宽的结果。若 ctx.agents 不可用,所有子代理调用都会被拒绝(fail-closed)。
ctx.approval.request(),不渲染自定义阻塞 UI。allowed-once 视为通过;rejected、cancelled、unavailable 全部拒绝。approvalTimeoutMs(默认 30,000 ms)到期即拒绝,并标记 timedOut;审计结果记为 timeout。apply 时 ctx.approval 不存在只记 warning;真正需要审批而服务仍缺失时,显式拒绝并写明“approval is required but ctx.approval is unavailable”,不会静默等待到超时。