Back to skill

Security audit

QMD Plus

Security checks for vulnerabilities and agentic risk

Overview

The skill is for local Markdown search, but it uses broad command/MCP authority and optional unpinned package and LLM integrations that could expose indexed notes or queries if installed carelessly.

Install only if you are comfortable giving QMD and MCP-enabled agents access to the Markdown collections you add. Use a dedicated non-sensitive collection, avoid searching secrets or private data through external LLM expansion, pin reviewed package versions, and remove broad npx or placeholder LLM command permissions unless you explicitly need them.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:293
Finding
Unpinned Third-Party Package Installation and Execution## Vulnerability Details **File Location**: `SKILL.md:5`, `SKILL.md:172`, `SKILL.md:293`; `references/mcp-setup.md:5-7` **Vulnerability Type**: Unpinned and mutable third-party dependencies **Risk Level**: Medium ### Vulnerable Code `SKILL.md:5`: ```yaml compatibility: Requires qmd CLI or MCP server. Install via `npm install -g @tobilu/qmd`. ``` `SKILL.md:172`: ```bash npm install -g @tobilu/qmd ``` `SKILL.md:293`: ```bash RESPONSE=$(npx @anthropic/claude-code --prompt "$PROMPT" --max-tokens 1000) ``` `references/mcp-setup.md:5-7`: ```bash npm install -g @tobilu/qmd qmd collection add ~/path/to/markdown --name myknowledge qmd embed ``` ### Technical Analysis The installation and integration instructions retrieve npm packages without pinning them to reviewed versions or verifying package integrity. The `npx` example can download and immediately execute the package version selected by the npm registry at invocation time. Likewise, the global QMD installation uses a mutable package reference and may execute npm lifecycle scripts during installation. Consequently, the code ultimately executed by these instructions can change after the skill has been audited. This is a supply-chain weakness rather than evidence that the currently referenced packages are malicious. Risk arises if a package maintainer account, registry entry, transitive dependency, or future release becomes compromised. Global installation increases the affected scope because package executables are placed in the user's global npm environment and may subsequently be invoked by other applications or sessions. ### Attack Path 1. An attacker compromises a referenced npm package, a maintainer account, or one of its transitive dependencies. 2. The attacker publishes a malicious version under the existing package name. 3. A user or agent follows the documented `npm install -g @tobilu/qmd` command or invokes the unpinned package throug ...[truncated 840 chars]
Remediation
## Remediation Suggestions 1. Pin every executable dependency to a reviewed exact version, for example `@tobilu/qmd@X.Y.Z` and `@anthropic/claude-code@X.Y.Z`. 2. Prefer project-local dependencies installed from a committed lockfile rather than global npm installations. 3. Use reproducible installation such as `npm ci` with a committed lockfile and verified registry integrity metadata. 4. Avoid invoking packages directly through unpinned `npx`. Install a reviewed version first and invoke its local executable. 5. Where compatible, install with lifecycle scripts disabled and explicitly review any required installation scripts before enabling them. 6. Document the expected package publisher, version, checksum, and trusted registry. 7. Periodically review pinned versions and their transitive dependencies before performing controlled upgrades.

T05 · Unauthorized Access and Privilege Escalation

Note
Location
SKILL.md:10
Finding
Overly Broad Tool Authorization Permits Unnecessary Package and External CLI Execution## Vulnerability Details **File Location**: `SKILL.md:10` **Vulnerability Type**: Excessive tool permissions and violation of least privilege **Risk Level**: Low ### Vulnerable Code ```yaml allowed-tools: Bash(qmd:*), Bash(node), Bash(jq), Bash(npx), Bash(your-llm-cli), mcp__qmd__* ``` ### Technical Analysis The skill authorizes `Bash(npx)` and a generic external LLM command even though the bundled wrapper directly requires only `node`, `jq`, and `qmd`. In particular, `npx` is not merely a local utility: it can retrieve and execute npm packages selected at invocation time. This permission is broader than the legitimate local query-expansion workflow requires. If an agent follows attacker-controlled or untrusted instructions while the skill is active, the broad authorization could be used as a code-execution channel. The generic `your-llm-cli` permission also lacks an exact, reviewed executable and argument policy. This finding identifies unnecessary attack surface in the declared authorization policy. The reviewed scripts do not themselves exploit these permissions, and no direct privilege escalation or malicious command was found. ### Attack Path 1. The skill is loaded with the declared tool permissions. 2. Untrusted content, a compromised external response, or a later malicious instruction directs the agent to invoke an attacker-selected package using `npx`. 3. The broad `Bash(npx)` authorization permits the invocation without requiring a permission specifically scoped to the reviewed workflow. 4. `npx` downloads and executes the selected package. 5. The package runs with the agent process's user privileges and can access resources available to that account. Alternatively, an instruction could steer the agent toward an unexpected executable represented by the generic `your-llm-cli` integration rather than a specifically reviewed provider command. ### Impact Assessment Exploitation could provide arbitrary code ...[truncated 376 chars]
Remediation
## Remediation Suggestions 1. Remove `Bash(npx)` from `allowed-tools` because it is not required by the bundled scripts. 2. Remove the placeholder `Bash(your-llm-cli)` permission from the default policy. 3. Authorize only the exact commands required by the implementation: the reviewed Node.js script, `jq` parsing, and narrowly scoped QMD query operations. 4. Require explicit user approval before enabling an external LLM client or any command capable of downloading executable content. 5. If external integration is necessary, define a specific reviewed executable and restrict its permitted arguments rather than granting a generic command capability. 6. Separate prompt-generation mode from external-provider execution so the default installation has no remote package-execution permission.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (10)

Agent Config Directory Access

High
Category
Agent Snooping
Content
## Configure MCP Client

**Claude Code** (`~/.claude/settings.json`):
```json
{
  "mcpServers": {
Confidence
90% confidence
Finding
Skill reads from agent configuration directories (.claude/, .codex/, .gemini/). These directories may contain API keys, personal settings, and other credentials that the skill has no legitimate need to access.

Vague Triggers

Medium
Confidence
93% confidence
Finding
The description says to use the skill when users ask to "search notes, find documents, or look up information," which are very broad phrases that overlap with common everyday requests. It does not provide narrower trigger constraints or negative examples to distinguish when this skill should activate versus other search or knowledge tools.

Natural-Language Policy Violations

Medium
Confidence
86% confidence
Finding
A substantial portion of the operational safety instructions is presented only in Chinese, while the rest of the document is mixed-language and does not state that the skill is intended exclusively for Chinese-speaking users. This creates a language/locale policy issue because important usage and safety guidance may be inaccessible unless the user implicitly accepts that locale.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
The documentation says the skill does not directly call an LLM, but later provides a wrapper that executes an external LLM command. This inconsistency can mislead users and reviewers about when data leaves the local environment, causing unsafe use with sensitive queries under a false privacy assumption.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The stated data flow claims only a generated prompt is sent externally, yet later text says expansion may use note content or context. If note text or collection-derived context is included in prompts, more sensitive data than users expect may be transmitted to third parties, creating a privacy and compliance risk.

External Transmission

Medium
Category
Data Exfiltration
Content
## HTTP API

```bash
curl -X POST http://localhost:8181/query \
  -H "Content-Type: application/json" \
  -d '{"searches": [{"type": "lex", "query": "test"}]}'
```
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The setup instructions tell users to globally install and enable a local MCP server over their indexed markdown content, but they do not warn that connecting this server to an agent/client makes those documents available to tool calls and possible model-driven retrieval. In a knowledge-search skill, that omission matters because users may index sensitive personal or corporate notes and expose them more broadly than intended.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The main prompt is written primarily in Chinese and states role/instructions in Chinese regardless of user preference. Although the script has some language handling for expansion output, the natural-language instruction layer still defaults to a specific language without documenting a justified locale restriction or offering a full language choice for the overall interaction.

Static analysis

No suspicious patterns detected.