Skill
dsh-plugin-audit
安装任何第三方 DeepSeek Harness (DSH) 插件或 agent preset 之前,审查它的源码, 判断是否安全、是否值得授予"宿主任意代码执行权"。当用户说"这个插件安全吗"、 "能不能装"、"审计/审查这个插件或 preset"、"dsh plugin add"、"帮我看看这个 第三方插件"、或贴出一个插件目录/仓库让评估,都要用它。即便用户没明说"安全"、 只要是在引入外部 DSH 代码,就应先做这次审计。
- Source
- wefio
- stars
- 2 stars
- License
- MIT
- Updated
- Updated 14 hours ago
Readme
# dsh-plugin-audit
一个**可复用的 DSH skill**(同时附带可独立运行的初筛脚本),用于在安装任何第三方 DeepSeek Harness 插件 / agent preset 之前,审查它的源码,帮你判断这件事安不安全。
> 这是仓库的入口说明。skill 本体的触发与执行规则见 [`SKILL.md`](SKILL.md);确定性初筛脚本见 [`scripts/scan.mjs`](scripts/scan.mjs);审计报告模板见 [`assets/report-template.md`](assets/report-template.md)。
---
## 为什么安装这个 skill
因为"装第三方插件"这件事,本质是授予它宿主机权限,而这件事**没有自动防线替你兜底**,只能靠你自己在装之前读一遍源码。这个 skill 把"读一遍源码"变成可复用、有结论的流程:
1. **它替你记住前提**:装第三方 host 插件 = 授予宿主任意代码执行权,让你不会因为 star 多、进了精选列表、别人说好用就跳过审查。
2. **它让审查有抓手**:先用脚本把危险信号定位出来,再有针对性地读、判断、给结论,而不是面对一个仓库无从下手。
3. **它逼出带证据的结论**:按固定模板输出,结论必须有文件 + 行号 + 语义判断,避免一句笼统的"应该没事"。
4. **它诚实地划定边界**:报告会写明"这只覆盖你给的这份源码",并提醒你**锁版本**——这是它区别于"自动安全扫描器"的地方,后者常给人虚假的安全感。
---
## 怎么安装和使用
### 安装
把整个 `dsh-plugin-audit/` 目录丢进你的技能根目录——`~/.agents/skills/` 或 `~/.dsh/skills/`。
### 使用
装任何第三方插件前,对 AI 说:
- "这个插件安全吗?"
- "审查这个 preset / 这个插件目录"
- 直接贴一个插件仓库地址或路径,说"帮我看看能不能装"
AI 会自己跑初筛脚本、读源码、按模板出一份带证据的审计报告(结论是"可装 / 需谨慎 / 不装",附"文件 + 行号 + 为什么")。
**也可以只当脚本用**(不做语义审查,只做确定性初筛):
```bash
node dsh-plugin-audit/scripts/scan.mjs <插件目录>
```
结果里的每条命中是"值得打开读的疑点",不是结论。
---
## 背景:为什么不能随意装插件
安装第三方插件,实质上是把一段未经审查的代码纳入本机的信任范围。就 DSH 的 host 插件而言,这个决定的影响比表面看起来大,原因有三:
**1. host 插件与宿主进程同权运行**
DSH 的 host 插件通过 `import()` 加载进运行 DSH 的那个 Node 进程,与 DSH 同权限运行,**不经过沙箱,也没有权限清单**。这意味着它的代码能够访问本机文件、读取 `~/.dsh/.credentials.yaml`、执行命令、发起网络请求——无论它的对外功能看起来多单一。功能是否无害,与它是否具备这些能力,是两件事。
**2. 安装链路没有自动化的可信校验**
从"插件被发布 → 被收录进列表 → 被推荐 → 你执行安装 → 被加载",整条链路**缺乏签名校验、版本锁定和来源完整性检查**。`awesome-dsh-plugin` 这类列表的收录依据是功能与流行度,**不代表代码被审计过**;star 数、README 质量、他人的使用经历,都不能作为安全证据。
**3. 插件是持续生效的,且可被静默更新**
host 插件并非一次性脚本:它会在每次会话启动时重新挂载。因此,代码若在后续版本中被修改——无论是上游仓库被攻击、维护者发布了带问题的更新,还是从第三方转存渠道拿到了被改动的副本——都会在下一次安装或更新时生效,而安装者往往无从察觉。
综上,安装第三方 host 插件等于授予它宿主机权限。当前生态不提供自动防线,风险控制依赖安装者自身的判断:**在安装前阅读源码,并锁定版本。**
---
## 背景:攻击方式,以及本 skill 如何拦截
下面的攻击手段按"能被拦截的程度"从高到低排列。
| 攻击方式 | 如何生效 | 本 skill 的拦截 |
|---|---|---|
| **① `!!js` 配置任意求值** | 恶意 preset 在 `agent.cordis.yml` 里写 `!!js (()=>{…})()`,挂载时被未沙箱化 `eval` 执行,可读凭据、外发、落持久化 | `scan.mjs` 匹配 `!!js` 及表达式内的 `process`/`getBuiltinModule`/`createRequire`;AI 再读表达式内容,命中即判"不装" |
| **② host 插件直接调用宿主能力** | 恶意包在 `apply()` 或模块顶层调用 `child_process`、`fs` 读凭据、`net`/`http` 外发、`vm`/`module` 等,因本来就在宿主进程里,无需绕过任何东西 | `scan.mjs` 按**模块能力**抓(`require("node:child_process")`、`from "fs"`、`import("vm")` 都覆盖);AI 读上下文判断用途是否正当 |
| **③ 生命周期脚本投毒** | `package.json` 的 `postinstall`/`preinstall`/`prepare` 在 `pnpm install` 时执行恶意代码 | `scan.mjs` 匹配这些脚本字段;AI 读脚本内容确认 |
| **④ `curl … \| sh` 远程执行** | 安装脚本从远端拉取并执行 shell,安装即中招 | `scan.mjs` 匹配 `curl\|wget … \| sh/bash`、`eval`、`bash -c` |
| **⑤ 未锁版本的来源漂移** | `git clone`/`git+https` 直连最新分支,上游被劫持或更新即换代码 | `scan.mjs` 标为 low 信号;**报告强制要求锁版本**作为补位 |
| **⑥ 混淆 / 动态构造** | `process["ch"+"ild_"+"process"]`、`import("\\x63hild")` 等,绕开关键词匹配 | 脚本匹配不到;**依赖 AI 语义审查**读透整段逻辑;仍是弱项,见下方边界 |
| **⑦ 依赖树深处投毒** | 恶意代码藏在一个无辜名字的依赖包里,随依赖链进入 | 本 skill 默认不深挖 `node_modules`;**靠锁版本 + 只信可信源** |
前五类(①–⑤)中的**常见直接形态**有确定性信号可抓,脚本先定位、AI 再判定;后两类(⑥⑦)是审计的固有盲区,skill 用"锁版本 + 信任原作者"来兜底,而不是假装能拦。
---
## 背景:它检查什么
审计分三层(详见 `SKILL.md`),各司其职:
| 层 | 谁做 | 检查什么 |
|---|---|---|
| **① 静态预筛** | `scripts/scan.mjs` | 读 `package.json` 的 `main`/`module`/`exports`/`bin` 定**真正入口**并无条件扫描;按**模块能力**抓危险信号(`child_process`/`fs`/`net`/`http`/`vm`/`module`/`worker_threads`,含 `node:` 前缀与动态 `import()`,区分 `import type` 不误报);`!!js`、生命周期脚本、`curl … \| sh`、`.npmrc` 是否禁用 lifecycle 脚本、发布物/源码并存检测、锁文件 `integrity`。附行号 + 上下文。 |
| **② 语义裁决** | AI(`SKILL.md`) | 读每处命中上下文,裁定 benign/malicious;并进行**静态语义还原**(识破变量间接/下标/拼接/转义等间接化构造,还原后按真实语义判定)。 |
| **③ 范围外风险声明** | AI(报告模板) | 声明静态与语义均不可及的风险维度:本地 RPC 无鉴权、插件间无隔离、审批社会工程、会话伪造。 |
为什么不能只靠脚本?因为这套威胁**正则判不了**:正则要么把防御代码误报成危险,要么漏掉混淆代码。所以**脚本定位疑点,AI 读懂语义下结论**,缺一不可。
---
## 一句话原则
> 第三方 host 插件的安全,唯一依据 = **亲手读过源码 + 锁死版本**。精选列表、star、README、别人推荐,都不是安全审计。装之前,先审。
## 碎碎念
这个发现是因为我的插件把我的新会话崩了
## License
MIT
Install
# Skills are files: copy them into $DSH_HOME/skills/dsh-plugin-audit (defaults to ~/.dsh/skills/dsh-plugin-audit)
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install wefio-dsh-plugin-audit from the hub