dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Agent Skill for DeepSeek Harness (DSH):装第三方插件前的静态安全审计 —— 扫出 eval、patch 层 !!js、安装期脚本、开机自启、凭据复制、出网域名与提示词注入面。Audit third-party DSH plugins before installing. Works with DSH, Claude Code, Codex, Cursor & any Agent Skills compatible agent.
中文 · English
Before you install a plugin, look at what it will touch.
An Agent Skill for DeepSeek Harness (DSH): a static security audit that surfaces eval, patch-layer !!js, install-time scripts, autostart entries, credential copies, network egress hosts, subprocess calls and prompt-injection surfaces — reported in three tiers: hard vetoes, capabilities to confirm, and things to merely know.
A third-party plugin is someone else's code running in the same process with the same privileges as your harness. Before installing, almost nobody can see what it does; after installing, you may not be able to undo it. This skill turns "take a look first" into a single command.
Note: This is a community project. It is not affiliated with, authorized by, or endorsed by DeepSeek.
DSH has production-grade protection for model behaviour (sandboxing, permissions, approvals) but no security design for plugin code. The four facts below come from the official Discussion #454 and third-party plugin security audit reports:
| Fact | Consequence |
|---|---|
| Plugins run in the same process and with the same privileges as the host | Whatever DSH can do, the plugin can do |
| The file sandbox blocks writes, not reads | Your ~/.dsh, .credentials.yaml, and .ssh are all readable |
Patch-layer !!js expressions run at load time | Nothing looks wrong in package.json — the code runs while loading |
| A malicious bundle executes on install | And a later remove does not undo a backdoor already dropped |
So with an unknown plugin the risk is not "it might not work well" — it is "you have no idea what it did".
Everything is pattern matching with context filtering (comment-only lines are skipped; one rule counts once per file):
Hard vetoes (VETO) — any single one is enough to stop
| Item | What matches |
|---|---|
| Dynamic evaluation | eval( / new Function / vm.runIn* |
| Patch injection | !!js (executes at load time) |
| Install-time scripts | postinstall / preinstall / prepare / prepublish |
| Autostart | Registry Run / schtasks / LaunchAgents / systemd units |
| Credential copying | Copying credential / .env / .ssh / id_rsa somewhere else |
Capabilities to confirm (RISK) — not accusations, just what it is allowed to do
| Item | What matches |
|---|---|
| Network egress | fetch / axios / WebSocket / net.connect |
| Telemetry export | telemetry / otel / exporter |
| Remote endpoints | Hardcoded public URLs (a separate host list is produced) |
| Credential reads | process.env / .credentials.yaml / .npmrc / id_rsa |
| Command execution | child_process / spawn / execFile / taskkill |
| Startup path | Touching cordis.patch.yml / dsh.profile.bundles |
| Instruction surface | Registering system prompts, agent/pre-step, injecting session messages |
| Untrusted content into prompts | The "read external content → concatenate into a prompt" shape |
| File writes | writeFile / appendFile / rmSync / unlinkSync |
| Supply chain | git+ / github: / fetching remote code at runtime |
| Official package paths | Referencing or modifying node_modules/@deepseek-ai |
Observations (INFO) — good to know
Persistent polling / heartbeats / watchdogs (setInterval / watchdog); self-update and hot-reload (self-update / autoUpdate).
w3.org, github.com, json-schema.org, …) from real connection targets.One line to remember: a match is not malice, and zero matches are not safety. The script tells you where to look; the conclusion comes from reading the code.
The skill is named plugin-audit (this repository is named dsh-plugin-audit). Pick either route:
# Route 1: the skills CLI (DSH is not registered with the CLI, so borrow cline's
# directory mapping, which resolves to ~/.agents/skills/)
npx skills add kiterunner1/dsh-plugin-audit -g -a cline -y
# Route 2: clone by hand — the target directory must use the skill name plugin-audit
git clone https://github.com/kiterunner1/dsh-plugin-audit.git ~/.agents/skills/plugin-audit
Skill directories per agent:
| Agent | Project | User |
|---|---|---|
| DeepSeek Harness | <project>/.dsh/skills/ (rank 100) or <project>/.agents/skills/ (rank 200) | ~/.dsh/skills/ (rank 400) or ~/.agents/skills/ (rank 500) |
| Claude Code | <project>/.claude/skills/ | ~/.claude/skills/ |
| Codex | <project>/.codex/skills/ | ~/.codex/skills/ |
| VS Code Copilot | <project>/.agents/skills/ | ~/.agents/skills/ |
| Other compatible agents | Follow that agent's skill directory convention | Same as above |
No restart needed: DSH watches these directories, so a new skill enters the catalog on the next model step. To verify, ask your agent "is this plugin safe to install" — the skill should trigger. In DSH you can also load it directly with skill(plugin-audit).
The script lives inside the skill directory; resolve it against the skill's own base directory:
# Audit a directory
pwsh -File "<base>/scripts/audit-plugin.ps1" -Path <plugin-directory>
# Audit by package name: resolved under <DSH_HOME>/profiles/*/node_modules and npm global
pwsh -File "<base>/scripts/audit-plugin.ps1" -Path <package-name>
# Several targets: comma-separated (repeating -Path raises a binding error)
pwsh -File "<base>/scripts/audit-plugin.ps1" -Path ./plugin-a,./plugin-b
# Machine-readable
pwsh -File "<base>/scripts/audit-plugin.ps1" -Path <directory> -Json
With a package name you do not need the full @scope/name — name also finds @scope/name. The script is read-only: it changes nothing and installs nothing.
(Format illustration; the figures come from a real run, with the package name, repository and line numbers anonymised.)
═══ 插件安全审查:<plugin-name> ═══
目录 : ~/.dsh/profiles/web/node_modules/<plugin-name>
包/版本 : <plugin-name>@1.2.3 license=MIT
规模 : 源文件 25 依赖 1 开发依赖 3 .git=False
dsh 字段: bundle, client, compatibility
结论:未命中硬否决项 —— 请核对下方能力/域名清单后决定
硬否决项 0 条 · 需确认能力 6 类 · 观察项 0 类
── 能力清单(不是指控,是"它有权做什么")──
[出网能力] 2 个文件命中 — 发起网络请求(看下方域名清单:连了谁、传了什么)
lib/client.js:3 fetch( (x1)
[供应链] 1 个文件命中 — 非固定来源依赖 / 运行时拉远端代码
package.json:96 git+ (x1)
[凭据读取] 4 个文件命中 — 读取环境变量/凭据(与出网组合即为外传面)
lib/config.js:77 process.env (x1)
[启动路径] 1 个文件命中 — 触碰 DSH 启动组合(patch/bundles):写坏即起不来
package.json:21 cordis.patch.yml (x2)
[文件写入] 2 个文件命中 — 写/删文件(看写到哪:自己目录内 vs 全盘)
lib/store.js:130 writeFileSync( (x1)
(The report itself is Chinese-only for now; -Json gives you a locale-neutral structure.)
Pattern matching only narrows the field. These four must be read by a human:
package.json → scripts (especially postinstall / prepare) and the dsh field.cordis.patch.yml in full — above all, whether it contains !!js.git+ / github: / remote code fetched at runtime.Do not install straight into the profile you use daily. Use a throwaway profile:
dsh plugin --profile tmp-audit add <package or github:owner/repo#<commit>>
dsh --profile tmp-audit --dump-config # check that the composition resolves
Two rules: stop the running DSH before installing plugins, otherwise profiles/<name>/node_modules gets deleted half-way and you are left with a profile that runs now and dies on restart; and pin dependencies to a commit (github:owner/repo#<sha>) instead of letting them drift with the default branch.
pwsh) on Windows, macOS, or Linux.DSH_HOME / USERPROFILE / HOME; it assumes nothing about your username or install location.Q: Can it miss things? Yes. This is static pattern matching, so it only sees code that looks like a dangerous behaviour. Obfuscation, dynamically assembled strings, and runtime downloads all get past it. Its purpose is to make blind installs less likely — not to replace an audit.
Q: Does a VETO hit mean the plugin is malicious?
Not necessarily. A plugin with !!js inside a documentation string will match too. Treat VETO as "stop and confirm by hand", not "guilty".
Q: Why is reading cordis.patch.yml still necessary?
Because patch-layer !!js executes at load time, sits outside the normal JS entry point, and is easy to miss in a static scan — and a broken patch can stop DSH from starting at all.
Q: Does it work for non-DSH plugins?
Yes. It scans for what code touches, which is host-agnostic. Only a few rules (dsh field, cordis.patch.yml, @deepseek-ai paths) are DSH-specific and simply will not match elsewhere.
dsh-plugin-audit/
├── SKILL.md # skill entry: when to use, how to run, how to read, trial-install discipline
├── README.md / README.en.md
├── LICENSE # MIT
├── .gitattributes
└── scripts/
└── audit-plugin.ps1 # the audit script (read-only)
name in kebab-case; a tight description (DSH truncates catalog descriptions at 500 characters by default); progressive disclosure in the body.MIT — see LICENSE.