dsh-plugin-security
Verifieddsh-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 · 插件安全门
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 随插件自动注册,无需手动链接。
扫描:不漏检
每个插件的每个版本只做一次完整检查,结果按 版本 + 内容指纹 + 规则版本 记录;代码或规则变化会重扫。扫描在以下时机触发:
- 本插件启动时(首次安装后的第一次启动即全量扫描)。
- 通过插件管理器安装、移除、启用或禁用插件之后。
- profile 重新组合之后(CLI 安装或手改配置后由热重载加载)。
- 调用拦截遇到当前版本没有记录的插件时,先扫描该插件再判断。
无法扫描的插件(找不到包、扫描失败)不会被静默放行,而是像高危插件一样询问。依赖审计因网络失败记为「未知」时不会当作通过:下次扫描会重试,调用时也会补扫(每个插件 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