Back to skill

Security audit

DSH Plugin Development

Security checks for vulnerabilities and agentic risk

Overview

This is mostly a coherent DSH plugin-development guide, but it includes unsafe helper/template behavior that can execute code or persist repository-derived guidance beyond the current project.

Install only if you are comfortable treating this as a development guide with executable helper scripts. Prefer the Python probe, avoid the Bash probe with untrusted repository paths, do not run the sample npx MCP bundle until you replace and review the package, and do not write findings from untrusted forks into global agent memory.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/dsh-api-probe.sh:71
Finding
User-Controlled Repository Path Enables JavaScript Injection in the Bash Probe<![CDATA[ ## Vulnerability Details **File Location**: `scripts/dsh-api-probe.sh:71` **Vulnerability Type**: JavaScript injection through unsafe string interpolation **Risk Level**: High ### Vulnerable Code ```bash REPO="" QUIET=0 for a in "$@"; do case "$a" in --quiet) QUIET=1 ;; *) REPO="$a" ;; esac done # ... LIVE_VER="$(node -e "try{console.log(require('$REPO/package.json').version||'unknown')}catch(e){console.log('unknown')}" 2>/dev/null || echo unknown)" ``` ### Technical Analysis The repository path originates from a command-line argument or the `DSH_REPO` environment variable. It is then interpolated directly into JavaScript source passed to `node -e`. Shell quoting does not make this safe at the JavaScript layer. A single quote in the repository path can terminate the JavaScript string passed to `require()`. Additional JavaScript statements embedded in the path can then be evaluated by Node.js. The preceding repository checks only verify that expected directories exist. They do not reject JavaScript metacharacters or otherwise prevent the path from changing the syntax of the generated program. The Python probe does not have this flaw because it passes values as subprocess argument-array elements instead of constructing executable source from them. ### Attack Path 1. An attacker creates or supplies a repository directory whose name contains a JavaScript payload. 2. The attacker creates the minimum expected directory structure, such as `packages/` and `vendor/loader/`, so the repository guard accepts it. 3. The victim or Agent runs the recommended Bash probe against that path: ```bash bash scripts/dsh-api-probe.sh "<attacker-controlled-path>" ``` 4. The path is inserted into the source string passed to `node -e`. 5. Embedded JavaScript breaks out of the `require()` path and invokes functionality such as `node:child_process`. 6. The injected code executes with the same operating-system privileges as the user or Agent running ...[truncated 487 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Do not interpolate filesystem paths into JavaScript source. Pass the package path as a separate argument: ```bash LIVE_VER="$( node -e ' try { console.log(require(process.argv[1]).version || "unknown") } catch { console.log("unknown") } ' "$REPO/package.json" 2>/dev/null || echo unknown )" ``` Additional hardening measures: 1. Make the Python probe the only recommended implementation unless Bash compatibility is essential. 2. Add a regression test using repository paths containing single quotes, spaces, parentheses, semicolons, and newline characters. 3. Avoid `node -e` whenever structured data can be read with a parser that accepts a filename argument. 4. Canonicalize the repository path before use, while recognizing that canonicalization alone does not replace safe argument passing. ]]>

T08 · Insecure Dependencies

Error
Location
assets/minimal-bundle/cordis.patch.yml:10
Finding
Copy-Ready Bundle Executes a Registry Package and Exposes an API Key to It<![CDATA[ ## Vulnerability Details **File Location**: `assets/minimal-bundle/cordis.patch.yml:10-29` **Vulnerability Type**: Unsafe third-party package execution with credential forwarding **Risk Level**: High ### Vulnerable Code ```yaml command: npx args: - -y # ⚠️ 版本号必须写「精确版本」。npx 会去 registry 取包并直接执行, # 写成浮动规格(省略版本 / latest / ^1 / ~1.x)意味着**每次启动执行的 # 都是当时的线上最新版** —— 这份配置被审阅之后,实际跑的代码仍然会变。 # 上游被攻陷、发布恶意新版本、形近包抢注,都会直接落到本机。 # 要升级,必须显式改这一行并重新审阅;`1.2.3` 是占位,换成真实版本。 - my-mcp-server@1.2.3 env: # 子进程环境会被清洗:凡是 /KEY|PASSWORD|SECRET|TOKEN/i 形状的名字 # 以及所有 DSH_* 变量都会被删掉。要传的凭据必须在这里显式列出。 # # ⚠️ 这里列出的每一个凭据,**那个被下载下来的子进程都能读到**,且它与 # DSH 同权限运行(可读写文件、可发网络请求)。只列这一个集成真正需要的 # 那一把,并优先用**低配额、可随时撤销**的专用 key,别用通用主 key。 MY_API_KEY: !!js process.env.MY_API_KEY ?? '' ``` ### Technical Analysis The bundle is provided as a copy-ready asset and starts an npm registry package through `npx -y`. The package identifier is a placeholder rather than a verified dependency selected by the user. Although the example pins `1.2.3`, version pinning only prevents unreviewed version drift. It does not establish package authenticity, prevent typosquatting or dependency confusion, or verify the integrity of the selected artifact and its transitive dependencies. The same configuration explicitly grants the downloaded process access to `MY_API_KEY`. The child process runs with the DSH process's operating-system permissions and can read accessible files, write to the workspace, and initiate network connections. The comments correctly disclose this risk, but disclosure does not prevent accidental execution if the example is copied without replacing and reviewing the placeholder. ### Attack Path 1. A developer copies the minimal bundle as instructed. 2. The placeholder package identifier remains unchanged, or it is replaced with a visually similar untrusted package. 3. The developer supplies `MY_API_KEY` in the DSH environment. 4. DSH starts the MCP integration ...[truncated 866 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Make the example disabled by default: ```yaml disabled: true ``` 2. Use an intentionally non-resolvable identifier such as `REPLACE_WITH_REVIEWED_PACKAGE` rather than a plausible registry package name. 3. Require the user to replace the identifier, verify the publisher and package provenance, and explicitly enable the entry. 4. Document integrity verification through a lockfile, package-manager integrity metadata, or an internally reviewed registry. 5. Avoid forwarding credentials in the generic template. Show a commented placeholder instead: ```yaml # MY_API_KEY: !!js process.env.MY_API_KEY ?? '' ``` 6. Require dedicated, low-quota, narrowly scoped, and revocable credentials for third-party subprocesses. 7. Where feasible, sandbox the subprocess with restricted filesystem and network access. 8. Review transitive dependencies in addition to pinning the top-level package version. ]]>

T02 · Agent Memory Poisoning

Warning
Location
references/00-version-gate.md:153
Finding
Repository-Derived API Claims Are Directed into Persistent Agent Memory<![CDATA[ ## Vulnerability Details **File Location**: `references/00-version-gate.md:153-165` **Additional Locations**: `scripts/dsh-api-probe.py:384`, `scripts/dsh-api-probe.sh:303` **Vulnerability Type**: Persistent Agent-memory poisoning **Risk Level**: Medium ### Vulnerable Instruction ```text 1. Look at the STALE entry and locate the mismatched M-tier fact. 2. Enter <repo>, read the source, and identify the current correct usage. 3. Update the corresponding entry in references/api-claims.md. 4. Update the corresponding assertion pattern in scripts/dsh-api-probe.sh. 5. If templates are affected, update references/02-templates*.md, 03-api-cookbook.md, and related files. 6. Run the probe again and confirm zero STALE results. 7. Write “what API changed from what to what” into ~/.workbuddy/memory/. ``` The executable probes repeat the instruction: ```python log(" 2) 把结论写进 ~/.workbuddy/memory/ 并在交付物里注明「已对 <commit> 核验」;") ``` ### Technical Analysis The workflow explicitly directs the Agent to write conclusions into `~/.workbuddy/memory/`, a persistent cross-session state location. The conclusions are derived from the selected source repository. The Skill also supports externally selected repositories through its synchronization workflow, including a custom `--repo <URL>` option. If the selected repository is an untrusted fork, compromised mirror, or attacker-controlled checkout, source content can cause the Agent to derive false API rules. Persisting those rules globally allows the resulting misinformation to affect future tasks that are unrelated to the repository where it originated. The instruction does not require explicit user approval for the cross-session write, constrain the memory entry to a specific project, or require a trusted repository identity. Recording the commit alone is insufficient if the repository origin itself is untrusted. ### Attack Path 1. An attacker persuades the user or Agent to inspect a modified DSH checkout, fork, mi ...[truncated 986 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the unconditional instruction to write repository-derived conclusions into global Agent memory. 2. Store findings in a project-local, reviewable file such as: ```text docs/dsh-api-verification.md ``` 3. Bind every finding to all of the following: - Canonical repository URL. - Verified remote identity. - Full commit hash. - DSH version. - Verification date. 4. Require explicit user confirmation before any cross-session memory modification. 5. Reject or prominently mark findings derived from custom repositories, mirrors, or forks unless their trust has been independently established. 6. Treat repository text as untrusted data and never persist instructions found inside it. 7. If long-term memory is unavoidable, use a narrowly scoped namespace tied to the exact repository and commit, and ensure unrelated sessions do not consume it automatically. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (76)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The description claims broad DSH/Cordis plugin-development tooling: guiding plugin creation/modification, adding plugin features, debugging load issues, packaging/publishing plugins, enforcing version gates, probing live source checkouts, and tracking upstream breaking changes. The code chunk does none of that. Its actual purpose is narrow and different: validating whether file references inside a skill package resolve correctly and identifying invalid material paths, parent-directory references, and local absolute paths. While this could be a support utility in a larger packaging workflow, the declared purpose does not accurately represent this code chunk’s behavior, and several advertised capabilities are absent from the implementation shown.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The code chunk does not implement general plugin-development tooling, packaging, debugging, publishing guidance, version gating, live API re-verification, or breaking-change history tracking as described. Instead, it is a specialized analysis script for one narrow documentation-validation task: extracting slot names from a DSH repository and diffing them against the skill’s own documented slot list. While this could be loosely supportive of plugin authoring accuracy, its primary purpose and concrete behavior are materially different from the declared broad plugin-development skill.

Ae1

High
Category
analysis-evasion
Content
> **目标版本高于基线时**不要猜:`dsh-sync.sh` 拉源码(先经确认)→ 探针核验 → `dsh-version-diff.sh` 出差异。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
> 完整机制(腐化推导、三级全表、五种核验手段、网络不可达时的降级路径)见 `references/00-version-gate.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
> 完整机制(腐化推导、三级全表、五种核验手段、网络不可达时的降级路径)见 `references/00-version-gate.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
> 完整机制(腐化推导、三级全表、五种核验手段、网络不可达时的降级路径)见 `references/00-version-gate.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
1. **引用任何字段名 / 事件名 / 服务名 / 插槽名前,先查 `references/08-cheatsheet.md` 或 `references/api-claims.md`。** 查不到就 grep 源码,**不要凭印象写**。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
1. **引用任何字段名 / 事件名 / 服务名 / 插槽名前,先查 `references/08-cheatsheet.md` 或 `references/api-claims.md`。** 查不到就 grep 源码,**不要凭印象写**。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
12 个模板的完整代码、官方 7 类模板的逐字源码、常用 UI 插槽名速查(**节选,非全清单**),都在 `references/02-templates.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
12 个模板的完整代码、官方 7 类模板的逐字源码、常用 UI 插槽名速查(**节选,非全清单**),都在 `references/02-templates.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
12 个模板的完整代码、官方 7 类模板的逐字源码、常用 UI 插槽名速查(**节选,非全清单**),都在 `references/02-templates.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
12 个模板的完整代码、官方 7 类模板的逐字源码、常用 UI 插槽名速查(**节选,非全清单**),都在 `references/02-templates.md`。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
4. 追根究底(原始社区提交、行号级出处)→ `10-community-casebook.md`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
4. 追根究底(原始社区提交、行号级出处)→ `10-community-casebook.md`
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发实战补充-模板与踩坑.md 区间 64-1256 -->

# 第二篇 · 模板库(12 个,由易到难)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发实战补充-模板与踩坑.md 区间 64-1256 -->

# 第二篇 · 模板库(12 个,由易到难)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发实战补充-模板与踩坑.md 区间 1257-1620 -->

# 第三篇 · 踩坑百科(按症状检索)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发实战补充-模板与踩坑.md 区间 1257-1620 -->

# 第三篇 · 踩坑百科(按症状检索)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发指导手册.md 区间 254-360 -->

# 第 2 章 环境准备
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发指导手册.md 区间 254-360 -->

# 第 2 章 环境准备
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:J-official-conventions.md (全文) -->

# J. 官方包/插件工程约定(`docs/cookbook/adding-a-package.zh.md` + `packages/AGENTS.md`)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:J-official-conventions.md (全文) -->

# J. 官方包/插件工程约定(`docs/cookbook/adding-a-package.zh.md` + `packages/AGENTS.md`)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发实战补充-模板与踩坑.md 区间 1913-1924 -->

## 6.5 三种插件形态对照(**最容易搞混的一张表**)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发实战补充-模板与踩坑.md 区间 1913-1924 -->

## 6.5 三种插件形态对照(**最容易搞混的一张表**)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
---

<!-- ↓ 源:DSH插件开发指导手册.md 区间 2455-2554 -->

# 第 13 章 与 AI Agent 结对开发(本手册的用法)
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Static analysis

No suspicious patterns detected.