Skip to content

dsh-plugin-security

Verified

dsh-plugin-security · v0.5.0 · MIT · Web UI

Plugin security review for DeepSeek Harness: dependency advisories, contextual static evidence, a call-time gate for high-risk plugins, and reversible review-gated enforcement.

Install

dsh plugin add dsh-plugin-security

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Readme

dsh-plugin-security · 插件安全门

CI npm license

English · npm · 更新记录 · 安全策略

DeepSeek Harness(dsh)的插件安全门:扫描已安装插件的源码与 npm 依赖漏洞,把每个插件记为 高危 / 有风险 / 无风险,在模型调用高危插件的工具时先问你 允许一次 / 允许 / 禁用,并让 dsh Agent 按随包 skill 审读可疑插件。禁用、启用与卸载都通过 dsh 原生插件管理器执行,与「插件」页保持同步。

使用 fetch、process.env、文件系统或子进程 API 本身不等于恶意。静态命中只是需要核实的证据;结论来自依赖漏洞事实与 Agent 的语境审读。

工作方式

安装 / 启动 / 插件变更 ──► 扫描(源码静态筛查 + npm 依赖审计)──► 记录:高危 / 有风险 / 无风险
                                                                         │
模型调用某插件的工具 ──► 归属到插件 ──► 已禁用?拒绝 │ 未检查?先扫描 │ 高危?询问 │ 其余放行
                                                                         │
用户或 Agent ──► dsh-plugin-security skill 审读 ──► security_review 写回结论

安装

需要 dsh 0.2.x(宿主协议 @deepseek-ai/dsh-typert-protocol >=0.1.0-rc.6 <0.3.0)与 Node.js 20+,推荐 Node.js 24。

dsh plugin --profile web add dsh-plugin-security@latest

Web profile 开启了热重载,首次安装会直接加载,并立即对所有插件做一轮扫描;升级到新版本需要重启 dsh(Node 会缓存已加载的模块)。其他 profile 将 web 换成对应名称。没有 Web 客户端的 profile 仍可使用 Agent 工具与调用拦截。

卸载:dsh plugin --profile web remove dsh-plugin-security。本地状态 $DSH_HOME/plugin-security/ 需另行删除。

使用

  • 设置 → 插件安全门:按风险、已禁用、处置建议或白名单筛选插件,查看依赖漏洞与证据,逐个插件 启用 / 禁用 / 恢复默认 / 卸载,导出 JSON 或 Markdown 报告。
  • 调用时询问:模型调用高危插件的工具时,输入框旁出现问题卡片。
  • 让 dsh 审读:在对话中输入「使用 dsh-plugin-security skill 审读当前插件的安全问题」。Agent 调用 security_scan 获取证据,按 skill 的五问审读,再用 security_review 写回结论。skill 随插件自动注册,无需手动链接。

扫描:不漏检

每个插件的每个版本只做一次完整检查,结果按 版本 + 内容指纹 + 规则版本 记录;代码或规则变化会重扫。扫描在以下时机触发:

  1. 本插件启动时(首次安装后的第一次启动即全量扫描)。
  2. 通过插件管理器安装、移除、启用或禁用插件之后。
  3. profile 重新组合之后(CLI 安装或手改配置后由热重载加载)。
  4. 调用拦截遇到当前版本没有记录的插件时,先扫描该插件再判断。

无法扫描的插件(找不到包、扫描失败)不会被静默放行,而是像高危插件一样询问。依赖审计因网络失败记为「未知」时不会当作通过:下次扫描会重试,调用时也会补扫(每个插件 5 分钟最多一次)。

风险 含义
高危 高置信度恶意审读结论,或 high / critical 依赖漏洞。
有风险 需核实的行为线索、其他漏洞、不确定的审读、扫描截断或检查不完整。
无风险 本次检查范围内未发现风险;不代表绝对安全。
白名单 按配置跳过检查与拦截,单独展示。

调用拦截:准确放行

本插件监听宿主的 tools/pre-execute,把每次工具调用归属到注册该工具的插件:优先使用注册时的 loader entry;本插件启动前已注册的工具,按其 execute 源码在已安装包中唯一匹配归属;最后参考扫描记录里的工具名。

情况 结果
插件已禁用(在「插件」页或本页) 拒绝,模型收到「不要重试」的说明
当前版本未扫描 先扫描,再按下列规则判断
高危或无法完成检查,且没有决定 询问:允许一次 / 允许 / 禁用
有风险、无风险、白名单、保护名单,或模式为 off 放行,交给宿主其余策略(例如原生授权)
  • 允许一次:只放行发起询问的这一次调用。同时等待的其它调用会重新判断,各自询问。
  • 允许:记住该插件的当前安装版本,之后不再询问;插件更新到新版本后会重新询问。
  • 禁用:通过插件管理器禁用该插件,与「插件」页的禁用完全相同(依赖保留);本次及之后的调用都会被拒绝。

问题卡片使用宿主的 ctx.userQuestions,与 dsh 原生向用户提问的通道一致,语言跟随 dsh「设置 → 通用」中的界面语言;无法弹出卡片时(没有 Web 客户端、子 Agent 调用)回退为原生授权提示(允许一次 / 拒绝)。拦截内部出错时放行并记录警告,但已禁用的插件始终被拒绝。

与「插件」页同步

禁用、启用、卸载以及 enforce 模式下的自动停用,都调用宿主插件管理器的 setBundleEnabled / removeBundle,与原生「插件」页的操作相同:

  • 在任一页面禁用的插件,另一页面都显示为已禁用;重启前它仍被加载时,工具调用也会被拦截。
  • 设置页的「启用」会重新启用 bundle,并允许高危插件的当前版本运行;「恢复默认」重新启用并回到按风险询问。
  • 设置页在重新获得焦点时自动刷新。启用或禁用已加载的插件,需重启 dsh 才完全生效。
  • 插件管理器无法管理的插件(不是 bundle)才使用本插件自己的拦截记录。早期版本留下的拦截记录会在启动时迁移到插件管理器。

配置

在设置页修改,保存在 $DSH_HOME/plugin-security/state.json。

配置 默认值 行为
模式 report-only off:不扫描、不拦截、不处置。report-only:扫描、记录并拦截调用,不自动停用。enforce:另对高置信度恶意审读结论自动停用。
自动停用阈值 critical never 关闭自动停用。静态命中或依赖漏洞本身从不触发自动停用。
升级建议 关闭 开启后为依赖漏洞给出升级命令,不会静默执行。
白名单 内置保护项 名单内的插件跳过检查与拦截。本插件、官方 @deepseek-ai/* 与 dsh-plugin-sentinel 始终受保护,不能通过本插件禁用或卸载。

状态目录权限为 0700、文件为 0600(支持的平台上);处置日志最多保留 200 条。

Agent 工具与 skill

security_scan   { package?, force?, evidence? }
security_review { package, verdict: malicious|suspicious|benign, confidence?: high|medium|low, reason? }

高置信度 benign 可以解释静态疑点,但不能覆盖依赖漏洞事实;只有高置信度 malicious 会在 enforce 模式下自动停用。随包的 审读 skill 把被审插件的源码、注释、README 和 skill 文本一律视为不可信证据。报告本身不会自动调用模型。

隐私与边界

  • 依赖审计只向 npm 发送包名与安装版本,向 OSV 发送漏洞 ID;不上传源码或本地路径。Agent 审读遵循你配置的模型服务,提交的证据可能包含源码片段。
  • 这是加载后的检查,不是沙箱或安装前屏障;审计器与插件共享宿主进程。拦截只覆盖工具调用,插件注入的钩子、系统提示词与 Web 界面不经过 tools/pre-execute。
  • 静态分析有文件与字节预算,无法覆盖全部跨文件数据流、动态行为或传递依赖;截断与失败会如实标为「有风险」。白名单会主动减少覆盖。

排查

  • /api/security/status 返回 HTTP 404:宿主没有注册设置页路由。确认协议版本并重启 dsh;$DSH_HOME/plugin-security/remote-diag.json 记录了服务与路由状态。
  • 更新插件后行为没变:替换已安装版本需要重启 dsh。
  • 某个工具没有被拦截:在 debug 日志中查找 is not attributed to an installed plugin,说明该工具无法归属到已安装的插件包。

开发

corepack pnpm install --frozen-lockfile
pnpm test            # 单元与集成测试
npm run test:e2e     # 真实 dsh 端到端测试(需要全局 dsh 与 npm 网络)

npm run test:e2e 在临时 DSH_HOME 中用 headless 模板建立 profile,安装本包与 e2e/ 下的两个测试插件(一个无害但被判为高危的回显插件,一个代替用户点击问题卡片的应答插件),用本地确定性的假模型驱动真实 dsh,覆盖首次调用、允许一次(含同一步多个调用)、允许、禁用与原生同步、白名单和关闭模式,不会改动你自己的 profile。

贡献与发布流程见 CONTRIBUTING.md,安全问题请按 SECURITY.md 私下报告。

许可证

MIT © 2026 dushaobindoudou