Back to home

truelove-dreamer

dsh-plugin-vetting

DeepSeek Harness plugin: heuristic malware vetting for installed third-party plugins

Stars
0
Language
JavaScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-plugin-vetting

装插件前,先体检:第三方插件 = 进程内全权限代码,这个工具让"盲装"变成"知情安装"——恶意模式、越权路径、未检查依赖,一目了然。

威胁模型(先读这个)

DSH 插件在 harness 进程内执行,拥有完整权限。因此本插件不是安全边界——它是启发式绊线(类似杀毒软件):静态扫描插件源码,命中可疑模式就报告,从不执行插件代码不拦截(拦截会误伤正常插件)。

三类威胁,两种输出:

威胁输出含义
恶意(外传凭据、eval、持久化)risk 分数 → SAFE/LOW/MEDIUM/HIGH蓄意滥用,需人工核实
误伤(非恶意,但高权限路径写得太糙)suggest narrowing 建议区不扣分、不标可疑,只建议收窄权限
运行时动态加载(下载后 eval、远端模块)文档声明 + [REVIEW] 标记静态扫描看不到,不在扫描范围

fail-closed 视角:任何命中 eval / new Function / vm.runInNewContext 的插件,无论总分多少都标 [REVIEW: dynamic code execution present]——eval 是静态扫描最大的盲区,它的存在本身就应降级信任,而不是等凑够分数才 HIGH。

真正的根治方案应由 harness 提供"挂载前扫描钩子"——本插件是该思路的独立原型。

功能

能力说明
plugin_vet 工具 / /plugin-vet 命令$DSH_HOME/profiles/*/node_modules 下所有 dsh-plugin-*(含 @scope/dsh-plugin-*)第三方包
恶意规则(15 条)网络外传、凭据访问、代码执行/混淆、持久化、读会话日志、生命周期脚本(含 install/prepare/prepublishOnly——git 依赖安装时 prepare 也会执行)
误伤规则(3 条)home 目录宽松读取、字符串拼接路径、递归遍历 home——标为"建议收窄"而非可疑
传递依赖统计声明依赖数 + 就地扫描嵌套 node_modules/* 的生命周期脚本,报告"N 个未检查"
[REVIEW] 标记eval/new Function 命中即降级信任,不看总分
覆盖范围报告每个包报告"扫了 N 个文件、M 行代码、X 个依赖/脚本",让边界显式可见
运行时表面每个包报告 child_process / fetch / eval / socket 的出现次数——静态能告诉你插件运行时能触及哪些危险原语
官方包哈希基线(默认开)@deepseek-ai/* 豁免的同时记录内容哈希基线($DSH_HOME/.dsh-plugin-vetting/baseline.json);安装包与基线不一致 → 豁免自动失效并报警(供应链投毒检测)——从"信任名字"变"信任内容"
插件工具门禁(默认关)config.gate: "deny-unvetted" 时,tools 管线拒绝调用门禁安装后注册的工具(即插件提供的工具),除非工具名在 allowlistTools 白名单。挂载在 tools.guard(即 tools/pre-execute 同一道闸)——只拦"模型→插件工具"的调用面,不碰插件进程内代码
运行时绊线(可选,仅日志)config.monitor: true 时监控 harness 的 ctx.subprocess 通道,可疑命令记警告日志;只记不改
官方豁免@deepseek-ai/* 自动豁免(但见哈希基线)
白名单config.allowlist 放行可信插件

安装

包已声明 dsh.bundle manifest(根目录 cordis.patch.yml),一条命令自动挂载:

dsh plugin --profile web add dsh-plugin-vetting

手动挂载(可选,等价写法):

- insert:
    - id: plugin-vet
      name: dsh-plugin-vetting
      config:
        # monitor: true  # 可选:运行时子进程绊线(只记日志)
        # allowlist: [dsh-plugin-security-audit]
        #   # 白名单:可信插件(安全插件规则里引用密钥路径,启发式必然高分)

使用

  • 模型工具:plugin_vet
  • 斜杠命令:/plugin-vet

示例输出:

# Plugin vet — 2 third-party plugin(s) scanned
safe=1 low=0 medium=0 high=1

[HIGH] dsh-plugin-some-plugin@1.2.0 (score 12)
    - network-fetch: makes fetch network requests @ lib/index.js:8
    - eval: dynamic code execution — static scan cannot see what runs here; requires manual review @ lib/index.js:21 [REVIEW]
    suggest narrowing (not suspicion):
      - sloppy-home-read: reads under the user home with broad patterns @ lib/index.js:4
    deps: 3 declared, 2 nested scanned, 1 unchecked
      - nested dep evil-dep has lifecycle scripts: postinstall

> heuristic scan only: a clean result is not a security guarantee
> runtime-dynamic code (downloaded then eval'd, remote modules) is NOT in scope — static scan cannot see it

开发

npm test   # node --test,零依赖

诚实边界

  • 启发式扫描:恶意代码伪装成正常写法仍可能漏过;干净结果 ≠ 安全保证;
  • 运行时动态加载的代码(下载后 eval、require 远端模块)不在静态扫描范围——不要因扫描通过就放松警惕;
  • 本插件不做"插件进程内行为门禁":插件在 harness 进程内直接调 child_process/fetch/eval 不经过 harness 的 ctx.subprocess,绊线看不到、也拦不住。要真正门禁这类行为,需要 harness 把插件跑在受控执行环境(受限 worker/VM)里——那是架构级能力,超出单个插件范围,本插件明确不假装提供;
  • 绊线只监控 harness 子进程通道且只记日志,从不阻断(静态置信度不足以拦停,误伤比漏检更危险);
  • 已知误报类:安全类插件(如 credential-guard / security-audit)的规则里会引用密钥路径、外传域名,启发式必然高分——用 allowlist 白名单处理;
  • 传递依赖只做就地扫描(包内嵌套 node_modules)+ 声明计数;提升到宿主 node_modules 的依赖不会逐个深扫,未检查数如实报告;
  • 官方豁免按包名判断,但内容哈希基线让"信任名字"变成"信任内容"(不一致即报警)。