🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

插件安全门 dushaobindoudou/dsh-plugin-security

DeepSeek Harnessv0.4.7
dushaobindoudou8 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness 插件安全审查:依赖公告、上下文证据、AI 辅助审查,以及可回滚的强制执行。

31.5/100
综合分
2
GitHub 星标
227
npm 周下载
—/5
用户评分

数据截至 2026/10/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-plugin-security
npm 源 · dsh-plugin-security 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · market
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-plugin-security @ 0.4.7
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/10 21:26:35

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 39 处,展示前 37 条)
  • 读取本地文件
    lib/scan.js:42
    entries = readdirSync(base);
  • 读取本地文件
    lib/scan.js:75
    const pkgJson = JSON.parse(readFileSync(join(base, name, 'package.json'), 'utf8'));
  • 读取本地文件
    lib/state.js:62
    const stat = statSync(file);
  • 读取本地文件
    lib/state.js:69
    const raw = JSON.parse(readFileSync(file, 'utf8'));
  • 写入本地文件
    lib/state.js:86
    mkdirSync(dir, { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/state.js:88
    writeFileSync(tmp, `${JSON.stringify(doc, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
  • 写入本地文件
    lib/state.js:89
    renameSync(tmp, file);
  • 读取本地文件
    lib/disposition.js:105
    const raw = JSON.parse(readFileSync(file, 'utf8'));
  • 读取本地文件
    lib/disposition.js:112
    if (existsSync(file)) {
  • 读取本地文件
    lib/disposition.js:113
    if (!existsSync(`${file}.security-bak`)) copyFileSync(file, `${file}.security-bak`);
  • 写入本地文件
    lib/disposition.js:113
    if (!existsSync(`${file}.security-bak`)) copyFileSync(file, `${file}.security-bak`);
  • 写入本地文件
    lib/disposition.js:116
    copyFileSync(file, `${file}.security-bak-${ts}`);
  • 读取本地文件
    lib/disposition.js:118
    const chain = readdirSync(dir).filter((n) => n.startsWith('package.json.security-bak-')).sort();
  • 删除本地文件
    lib/disposition.js:120
    try { unlinkSync(join(dir, stale)); } catch { }
  • 写入本地文件
    lib/disposition.js:125
    writeFileSync(tmp, `${JSON.stringify(doc, null, 2)}\n`, 'utf8');
  • 读取本地文件
    lib/disposition.js:127
    JSON.parse(readFileSync(tmp, 'utf8'));
  • 写入本地文件
    lib/disposition.js:128
    renameSync(tmp, file);
  • 读取本地文件
    lib/disposition.js:161
    if (typeof pluginDir === 'string' && pluginDir.length > 0 && existsSync(pluginDir)) {
  • 写入本地文件
    lib/disposition.js:163
    renameSync(pluginDir, `${pluginDir}${QUARANTINE_SUFFIX}`);
  • 写入本地文件
    lib/disposition.js:184
    renameSync(candidate, pluginDir);
  • 执行外部命令固定命令
    lib/remote.js:31
    const child = spawn('pnpm', args, { cwd, env: process.env });
  • 写入本地文件
    lib/remote.js:325
    mkdirSync(join(resolved.env.dshHome, 'plugin-security'), { recursive: true });
  • 写入本地文件
    lib/remote.js:326
    writeFileSync(join(resolved.env.dshHome, 'plugin-security', 'remote-diag.json'), JSON.stringify(probe, null, 2));
  • 读取本地文件
    lib/paths.js:16
    return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
  • 读取本地文件
    lib/paths.js:93
    return existsSync(join(dir, 'package.json')) ? dir : null;
  • 读取本地文件
    lib/collect.js:30
    return JSON.parse(readFileSync(path, 'utf8'));
  • 读取本地文件
    lib/collect.js:39
    const stat = statSync(path);
  • 读取本地文件
    lib/collect.js:41
    return readFileSync(path, 'utf8');
  • 读取本地文件
    lib/collect.js:115
    entries = readdirSync(dir, { withFileTypes: true });
  • 读取本地文件
    lib/collect.js:139
    const stat = statSync(abs, { throwIfNoEntry: false });
  • 读取本地文件
    lib/collect.js:180
    if (existsSync(candidate)) return candidate;
  • 读取本地文件
    lib/skill.js:34
    const skill = parseSkill(readFileSync(path, 'utf8'));
  • 读取本地文件
    lib/manager.js:87
    if (typeof dir !== 'string' || dir.length === 0 || existsSync(dir) || !existsSync(`${dir}${QUARANTINE_SUFFIX}`)) return false;
  • 写入本地文件
    lib/manager.js:89
    renameSync(`${dir}${QUARANTINE_SUFFIX}`, dir);
  • 读取本地文件
    lib/rules.js:270
    return JSON.parse(readFileSync(path, 'utf8'));
  • 读取本地文件
    lib/rules.js:573
    if (!existsSync(root)) return [];
  • 读取本地文件
    lib/rules.js:580
    entries = readdirSync(dirPath, { withFileTypes: true });
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-api-gateway@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-invariants@deepseek-ai/dsh-typert-registry@deepseek-ai/dsh-typert-protocol
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 依赖公告审查
  • 上下文证据收集
  • AI辅助安全审查
v0.5.02026-10-11
· 新增 · 调用门禁。每次工具调用都归属到注册它的插件,并在宿主的 tools/pre-execute 瀑布流中检查。调用高风险插件,或安全检查没能完成时,通过宿主用户提问卡片询问「仅本次允许 / 允许 / 禁用」,无法显示卡片时回退到原生审批提示。「仅本次允许」只放行发起询问的那次调用;「允许」对已安装版本长期有效;「禁用」会禁用该插件。 · 插件管理器同步。禁用、启用、卸载和强制模式自动禁用都会调用宿主插件管理器(setBundleEnabled / removeBundle),与原生插件页操作一致。在任一页面禁用的插件,只要还处于加载状态就会被拒绝;旧版本存下的门禁拦截记录会在启动时迁移到插件管理器。 · 设置页:每个插件的启用 / 禁用 / 重置、已禁用标签页、原生禁用状态、聚焦时刷新。 · 三级风险(高 / 有风险 / 无)和声明的工具名随每条扫描记录一起保存,并在报告和智能体工具中展示。 · 扫描触发:除启动外,还包括插件管理器变更、配置档重组(热重载下的命令行安装)以及调用时按需触发。 · 内置的审查技能会自行注册到宿主技能目录,不再需要手动关联技能。 · npm run test:e2e:在隔离的 DSH_HOME 中运行真实的 headless dsh,配一个无害的高风险测试插件、一个按脚本作答的问答器和一个确定性的本地模型。 · 仓库:安全策略、issue 与 pull-request 模板、Dependabot、CODEOWNERS、e2e CI 任务,以及带来源证明的手动 npm 发布工作流。 · 变更 · 任何扫描都无法记录的插件改为询问,而不是直接放行;结果未知的依赖审计由下一次扫描和调用时重试(每个插件最多每五分钟一次)。 · 强制重扫会保留智能体对未变更内容的审查;同一包的旧记录会被丢弃。 · 门禁启动前注册的工具按其 execute 源码文本归属,因此对新安装插件的首次调用也会经过门禁(由 e2e 运行发现)。 · 宿主渲染的文本(提问卡片、拒绝消息)跟随设置 → 通用里设定的 dsh UI 语言,每次提问时读取;DSH_LOCALE 可覆盖,进程区域设置为兜底。 · 筛查修订 risk-status-4:升级后对已有记录重扫一次。 · 修复 · security_review 在已存下判定结果后抛出 ACTION_ICON is not defined。 --- npm:dsh-plugin-security@0.5.0 · integrity sha512-FqMfHzGsG+lNEM+7B39wQir+GaU8qoKSlzOYKgxLiojl/XeVrTpZJN7J1JKiPGCAg7TWtrk/o/0X7Q6kwUUjWA== 安装或升级:dsh plugin --profile web add dsh-plugin-security@0.5.0,然后重启 dsh。
v0.4.62026-10-10
DeepSeek Harness 插件安全审查,含依赖公告、上下文证据、AI 辅助审查与可回滚的强制处置。 · 更新 · 修复设置页 RPC HTTP 404 及路由生命周期注册。 · 降低误报:能力匹配与行为证据分开记录,移除 A–F 评级。 · 恢复处置配置,新增可搜索的风险与白名单 tab、逐插件操作、导出和紧凑统计。 · 发布中英文文档、标准 dsh 包与客户端元数据,以及共享协议 peer 声明。 · 安装 dsh plugin --profile web add dsh-plugin-security@0.4.6 升级后重启宿主,需要 @deepseek-ai/dsh-typert-protocol@0.2.0-rc.2 宿主协议。 扫描在插件加载后进行。API 匹配不等于恶意判定;自动隔离需同时满足:目标未受保护、处于强制处置模式、已开启阈值、审读结论为高置信度恶意。 · 验证 本地及 GitHub Actions 的 Node.js 22 和 24 上通过 91 项测试,并验证了隔离 tarball 导入、dsh 配置档安装和包配置层。 npm 包 · 英文 README · 中文 README
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-plugin-security · 插件安全门 English · npm · 更新记录 · 安全策略 DeepSeek Harness(dsh)的插件安全门:扫描已安装插件的源码与 npm 依赖漏洞,把每个插件记为 高危 / 有风险 / 无风险,在模型调用高危插件的工具时先问你 允许一次 / 允许 / 禁用,并让 dsh Agent 按随包 skill 审读可疑插件。禁用、启用与卸载都通过 dsh 原生插件管理器执行,与「插件」页保持同步。 使用 fetch、process.env、文件系统或子进程 API 本身不等于恶意。静态命中只是需要核实的证据;结论来自依赖漏洞事实与 Agent 的语境审读。 工作方式 安装 / 启动 / 插件变更 ──► 扫描(源码静态筛查 + npm 依赖审计)──► 记录:高危 / 有风险 / 无风险 │ 模型调用某插件的工具 ──► 归属到插件 ──► 已禁用?拒绝 │ 未检查?先扫描 │ 高危?
展开完整文档(README 剩余 1 节)
dsh-plugin-security · 插件安全门

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
预览分享卡片长什么样 ↓dushaobindoudou/dsh-plugin-security
分享 · DeepSeek Harness Hub
dushaobindoudou/dsh-plugin-security

DeepSeek Harness 插件安全审查:依赖公告、上下文证据、AI 辅助审查,以及可回滚的强制执行。

这是你的仓库?认领条目

回到顶部