Skip to content
dsh.fish
Bundle

dsh-plugin-gate

Installation safety gate & data-protection guard for DeepSeek Harness: 60 static signature rules (31 high/24 medium/5 low) scan plugin sources for malicious install scripts, credential theft, obfuscation, persistence and network callbacks before 'dsh plugin add', plus 12 destructive-command patterns and workspace-boundary checks against accidental deletion. | 安装安全闸门与数据保护闸:60 条静态签名规则(31 高危/24 中危/5 低危)扫描插件恶意行为、持久化与外传,12 种危险命令模式与边界检查拦截误删。

Source
863683348
stars
1 stars
License
MIT
Updated
Updated 13 days ago

Readme

# dsh-plugin-gate

**Installation safety gate & data-protection guard for DeepSeek Harness — 60 static signature rules (31 high / 24 medium / 5 low) scan plugin sources for malicious install scripts, credential theft, obfuscation and network callbacks before you run `dsh plugin add`, and 12 destructive-command patterns plus workspace-boundary checks stop `rm -rf`-class accidents before they happen.**

The plugin marketplace is growing fast (thousands of entries), and malicious code mixed into a plugin is only a matter of time. `dsh-plugin-gate` gives the agent a `gate_scan` tool that inspects a plugin source — a **local directory** or an **npm tarball** — for the classic malware shapes:

| Domain | What it checks |
|---|---|
| **Scripts** | npm lifecycle scripts (pre/install/postinstall), exec/spawn/shell:true, curl|sh, encoded PowerShell, cmd/WSH launch, dynamic require |
| **Obfuscation** | eval / new Function / vm.runIn*, hex-escape floods, base64 blobs, char-array packing |
| **Permissions** | credential env reads (`OPENAI_API_KEY` etc.), ssh/aws/npmrc file reads, writes to system/home/dotfile paths, chmod 777, sandbox-escalation requests |
| **Network** | external URLs & hosts, fetch/axios/socket/WebSocket/DNS APIs, cloud-metadata endpoints (169.254.169.254), Discord/Telegram/Slack webhooks, .onion, read-then-send exfiltration shape |
| **Secrets** | hardcoded `sk-` keys, `ghp_` tokens, AWS keys, private key blocks, bearer tokens |
| **Supply chain** | exact-version direct dependencies checked against **Google OSV** (ranges and official @deepseek-ai packages skipped; configurable, offline-degrades) |

The gate is **read-only**: it never executes scanned code and never writes files.

## Install

In your DSH profile:

```bash
dsh plugin --profile <profile> add dsh-plugin-gate
# or add the bundle patch manually:
#   dsh --profile <profile> --patch ./node_modules/dsh-plugin-gate/cordis.patch.yml
```

## Usage

Ask the agent to scan a plugin before installing it (the plugin also injects prompt guidance that tells the agent to do this automatically):

```
gate_scan target: "npm:dsh-plugin-some-package"
gate_scan target: "npm:dsh-plugin-some-package@1.2.3"   # pinned version
gate_scan target: "./downloaded-plugin"                 # local directory
```

### v1.1 - Data-protection guard

Before any destructive operation, ask the agent to evaluate it with gate_guard (also injected into prompt guidance):

    gate_guard command: "rm -rf ./node_modules"
    gate_guard path: ".dsh-memory-setup/memory.json" action: "delete"

- **BLOCK** - device/root-level destruction (rm -rf /, rmdir /s /q, format, dd to a block device, mkfs, drive-root deletes): refuse.
- **WARN** - recursive/force deletes, targets outside the workspace, or critical files (memory.json, .git, ...): confirm the exact target first.
- **PASS** - no destructive signature detected.

Result shape:

```json
{
  "verdict": "BLOCK" | "WARN" | "PASS",
  "score": 254,
  "summary": { "high": 0, "medium": 1, "low": 3, "categories": { "network": 4 } },
  "network": { "hosts": [...], "unallowlisted": [...], "readAndSendFiles": [...] },
  "hits": [{ "rule": "fetch_call", "category": "network", "severity": "medium",
             "file": "lib/index.js", "line": 12, "evidence": "...", "hint": "..." }],
  "recommendations": [...]
}
```

### Verdict semantics

- **BLOCK** — at least one high-severity signature. Do not install until the maintainer ships a clean rebuild you can scan again.
- **WARN** — medium-severity patterns that need manual review (network I/O, home-path writes, base64 blobs). Inspect every hit in context.
- **PASS** — no risky signatures. Heuristic only — keep normal caution with unknown maintainers.

Context-aware rules: `exec()`/`execSync()` hits are downgraded when the file does not import `child_process` (typical `RegExp#exec` false positive); code-context rules (exec, eval, curl|sh, PowerShell…) are downgraded to low when found in **comments or documentation** (examples, not behavior) — while secrets and webhooks stay flagged even in comments. Dependencies installed from git/http/file URLs are flagged as `risky_dependency`, and >4000-char minified lines as `minified_line` (low).

## Configuration

| Key | Default | Meaning |
|---|---|---|
| `maxFiles` | 1000 | hard cap on scanned files per directory walk |
| `maxFileBytes` | 2 MiB | per-file text cap |
| `includeNodeModules` | false | descend into node_modules |
| `maxTarballBytes` | 32 MiB | npm tarball download cap |
| `allowlistHosts` | [] | hosts never listed as unallowlisted |
| `osvCheck` | true | query Google OSV for known vulnerabilities on exact-version deps |
| `osvMaxDeps` | 8 | max exact-version direct deps checked |
| `osvTimeoutMs` | 10000 | per-dep OSV query timeout |
| `promptSection` | true | inject agent guidance |
| `sectionOrder` | 5 | prompt section order |

## Development

```bash
node --check lib/*.js
node test/rules.test.mjs   # main-module mode (node --test is blocked in the DSH sandbox)
node test/scan.test.mjs
```

Pure logic lives in `lib/rules.js` (signatures), `lib/targz.js` (in-memory tar.gz), `lib/scan.js` (orchestration + verdict). The Cordis plugin is `lib/index.js`.

## Security

The gate never executes scanned content. It is a heuristic signature scanner — it can miss novel malware and over-flag innocent code. Review BLOCK/WARN hits yourself; see [SECURITY.md](SECURITY.md).

## License

MIT

Install

dsh plugin --profile web add github:863683348/dsh-plugin-gate

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source