Install verification: Ecosystem plugin: installs via dsh plugin add but declares no dsh.bundle and mounts no plugin capability — the L1-L5 install ladder does not rate it; the security scan still runs.Install verification details →
What it does
DeepSeek Harness plugin market: browse, search and install community plugins from the sidebar foot entry (host + web client halves, DSH plugin spec).
Installation
dsh plugin --profile web add github:Winnie-0721/dsh-plugin-market#v1.3.1Install method: GitHub · runtime test inconclusive (L5 unknown)
Verification & Compatibility○ Ecosystem plugin
Grouped by plugin version: each card lists the dsh versions actually tested against that artifact version and their install verdicts (L5 wins). Untested combinations are omitted — absence means untested, never assumed compatible. L1–L3 are a plugin-level static archive (independent of the dsh version — the same verdict on every dsh row): they sit in each row's level grid next to L4/L5, marked "static", while their evidence is stored once per plugin inside that row's "checks & evidence" instead of being duplicated per version.
External credentials (plugin-level): none detected
package manifest not collected — the declared range is unknown.
| plugin \ dsh | dsh 0.2.1-rc.2 current |
|---|---|
| v1.3.2 | · |
| v1.3.1 | ○ |
v1.3.2github2026-10-21
https://github.com/Winnie-0721/dsh-plugin-market
Ecosystem plugin: installs via dsh plugin add but declares no dsh.bundle and mounts no plugin capability — its level reads L5 · Ecosystem plugin.
v1.3.1github○ 1 ecosystem plugin2026-10-19
https://github.com/Winnie-0721/dsh-plugin-market
○dsh 0.2.1-rc.2current2026-10-19Ecosystem plugin
- • Node.js: v24.14.0
- • DSH: 0.2.1-rc.2
- • Plugin artifact: github · https://github.com/Winnie-0721/dsh-plugin-market#v1.3.1
ID: dsh-plugin-market-31@v1.3.1@dsh0.2.1-rc.2 · profile: l4-sandbox
Issued: 2026-10-19 · expires: 2026-10-26
View checks & evidence
↳ carried from earlier record dsh-plugin-market-31@v1.3.2@dsh0.2.1-rc.2 (l3-fullscan)
↳ carried from earlier record dsh-plugin-market-31@v1.3.2@dsh0.2.1-rc.2 (l3-fullscan)
↳ carried from earlier record dsh-plugin-market-31@v1.3.2@dsh0.2.1-rc.2 (l3-fullscan)
not present in web-profile loader inventory
L1–L3 are plugin-level static conclusions (baseline, identical across dsh versions): evidence is stored once per plugin.
Author badges
Embed the official badges in your README to showcase security & install-test status:
`[](https://www.dsh.so/artifact/dsh-plugin-market-31/)`Security Report
Two automated layers, neither a manual review: a static scan (per-plugin rule checks) and a model-driven dynamic security audit that covers only the subset static-flagged at warn or above and never executes plugin code.
Static low, dynamic medium — stricter wins → overall medium.
—v1.3.2git2026-10-21v1.3.2same versionclean · gitVet is an AST static scan (npm artifact or git source).
show static findings (12)
- criticalspawnShell · shell
verify/pack-inventory.mjs:32? spawnSync(line, { ...base, shell: true, ...opts }) - warningchildProcess · code-exec
plugin-market/lib/restart-helper.cjs:91const child = spawn(payload.execPath, payload.args, options) - warningchildProcessImport · code-exec
plugin-market/lib/restart.js:19import { spawn } from 'node:child_process' - warningnetIp · network
verify/adversarial-host.mjs:29process.env.DSHM_REGISTRY_URL = 'http://127.0.0.1:9/definitely-unavailable.json' - warningnetIp · network
verify/adversarial-host.mjs:142const SAME_ORIGIN = { origin: 'http://127.0.0.1:1', host: '127.0.0.1:1', 'content-type': 'application/json' } - warningchildProcess · code-exec
verify/lib/cdp.mjs:111const child = spawn(executable, args, { stdio: 'ignore', windowsHide: true }) - warningnetIp · network
verify/lib/cdp.mjs:112await waitForHttp(`http://127.0.0.1:${port}/json/version`, 30000, 'Edge 调试端口') - warningnetIp · network
verify/lib/cdp.mjs:113const targets = await waitForHttp(`http://127.0.0.1:${port}/json/list`, 10000, 'Edge target 列表') - warningchildProcess · code-exec
verify/pack-inventory.mjs:32? spawnSync(line, { ...base, shell: true, ...opts }) - warningchildProcess · code-exec
verify/pack-inventory.mjs:33: spawnSync(cmd, args, { ...base, shell: false, ...opts }); - warningnetIp · network
verify/probe-toggle-hot.mjs:27const base = `http://127.0.0.1:${port}` - warningnetIp · network
verify/probe-toggle-state.mjs:28const base = `http://127.0.0.1:${port}`
show 4 audit findings
- mediumRestart helper passes the host's full process.env on the child command line (base64 in argv)
plugin-market/lib/restart.js:79spawnRestartHelper() calls buildHelperCommand with `env: process.env`; buildRestartPayload copies every string entry into payload.env, which is JSON+base64 encoded into a single argv element passed as `node restart-helper.cjs <payload>`. On Linux /proc/<pid>/cmdline is world-readable, and the payload is also visible in `ps`/Windows process listings, so any local user (or any process that can read the command line) can decode API keys, tokens and proxy credentials while the helper lives (up to RESTART_HELPER_WAIT_MS = 60s).
- mediumHot-mount interpolates an unescaped package name into the generated include YAML
plugin-market/lib/hot-mount.js:401In the client-only branch the row is `{ id: `client-${packageName.replace(/[^A-Za-z0-9_.-]/g, '-')}`, name: packageName }` — the id is sanitised but the name is used raw, and resolveProfileEntry() passes names starting with '.', '/', 'file://' or 'cordis:' through unchanged. A package name containing a single quote (or a file:///absolute path that also has a real directory under node_modules declaring dsh.client) breaks out of the quoted scalar and lets the marketplace write arbitrary rows into a YAML file that the cordis Include loader then executes, i.e. attacker-chosen module loading in the
- lowRestart wall treats the wildcard bind address 0.0.0.0 as a loopback authority
plugin-market/lib/restart-policy.js:3490.0.0.0 is a bind address, not a loopback name; accepting it in the Host allow-list widens the DNS-rebinding wall for the restart endpoint beyond the intended localhost/127.0.0.1/::1 set. Exploitation still requires a loopback peer address (directLoopbackRequest) and a matching Origin, so no concrete bypass is demonstrated — this is a hardening gap.
- lowPrimary HTTP entry plugin-market/lib/index.js was not part of the harvested source
verify/adversarial-host.mjs:8All route handlers, the auth/session check and the mapping of request fields into restart/hot-mount options live in lib/index.js, which is absent from the provided files. Whether spawnRestartHelper receives attacker-controlled execPath/args/env, and whether install names are validated before hotMount, could not be verified; the residual risk of the restart and hot-mount paths is therefore higher than the audited code alone suggests.
Runtime code is mostly defensive, but the restart helper leaks the host environment on the command line and hot-mount interpolates unescaped package names into YAML.
Rule: the dynamic audit can only raise risk, never lower it (raise-only, never an exemption); a wrong raise is withdrawn by human review and the tier falls back to the static verdict. Overall verdict = the stricter of the two layers.
Disclaimer: the static scan and the dynamic security audit are both automated analysis, not a security guarantee. Always review what you install.
Activity
Last commit 2026-10-19 · activity: Active
• Repo created: 2026-10-03
• Stars: ★ 2 · Forks: 1
• Health: Active — committed within last 30 days
Source
Author README
View on GitHub ↗The author's original README from the repository — fetched live, unedited (the English page loads the default README).
