Back to skill

Security audit

Markdown Ai Rewriter

Security checks for vulnerabilities and agentic risk

Overview

This skill is broadly a Markdown AI rewriting tool, but it needs Review because it can load local project code in-process and route document content to externally configured AI endpoints.

Install only after reviewing the underlying npm package and launcher behavior. Avoid using this skill on confidential Markdown unless the chosen provider and endpoint are approved, pin dependencies exactly, disable or tightly scope auto-invocation, do not run it from untrusted project directories, and treat custom base URLs as sensitive because they may receive the full document content.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (3)

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/run.js:63
Finding

Untrusted Working-Directory Package Can Be Dynamically Imported and Executed

Content
View full analysis
/bin/node -> /lib/node_modules path.join(nodeBinDir, '..', 'lib', 'node_modules'), // Windows: node.exe sits next to npm's node_modules path.join(nodeBinDir, 'node_modules'), // Launcher-local node_modules (defense-in-depth for non-global installs) path.join(__dirname, '..', 'node_modules'), path.join(process.cwd(), 'node_modules'), ]; for (const root of candidateRoots) { const candidate = path.join(root, PINNED_PACKAGE, ...PINNED_ENTRY_RELPATH); try { if (fs.statSync(candidate).isFile()) return candidate; } catch (_) { // not present at this root; continue } } try { return require.resolve( `${PINNED_PACKAGE}/${PINNED_ENTRY_RELPATH.join('/')}`, { paths: candidateRoots }, ); } catch (_) { return null; } } async function runMdRewrite(cliArgs) { if (!Array.isArray(cliArgs) || cliArgs.some((a) => typeof a !== 'string')) { fail('Internal error: cliArgs must be an array of strings'); } for (const a of cliArgs) { if (a.length > MAX_ARG_LEN || CONTROL_CHAR_RE.test(a)) { fail('Internal error: cliArgs failed final safety check'); } } const entry = resolveCliEntry(); if (!entry) { fail( `'${PINNED_PACKAGE}' not found in any standard node_modules location. ` + `Install it first: npm install -g ${PINNED_PACKAGE}@${REQUIRED_VERSION}`, ); } // The imported CLI reads process.argv. Inject our validated argv. process.argv = [process.execPath, entry, ...cliArgs]; try { await import(pathToFileURL(entry).href); } catch (err) { fail(`Failed to invoke ${PINNED_PACKAGE}: $ ...[truncated 2242 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:117
Finding

Documentation Installs Unpinned Third-Party Packages

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.js:43
Finding

Arbitrary Provider Endpoint Override Bypasses the Declared Network Allowlist

Content
View full analysis
MAX_ARG_LEN) { fail(`Invalid ${label}: exceeds ${MAX_ARG_LEN} characters`); } if (CONTROL_CHAR_RE.test(value)) { fail(`Invalid ${label}: contains control characters`); } } function validateForwardArgs(args) { for (const arg of args) { assertSafeArg(arg, 'argument'); } } ``` ```js // The imported CLI reads process.argv. Inject our validated argv. process.argv = [process.execPath, entry, ...cliArgs]; try { await import(pathToFileURL(entry).href); } catch (err) { fail(`Failed to invoke ${PINNED_PACKAGE}: ${err && err.message ? err.message : err}`); } ``` The Skill documentation explicitly advertises a generic endpoint override: ```text --base-url (generic endpoint override) ``` Meanwhile, `config.json` declares a finite set of permitted network destinations: ```json "network": { "domains": [ "registry.npmjs.org", "api.openai.com", "api.anthropic.com", "*.openai.azure.com", "generativelanguage.googleapis.com", "api.deepseek.com", "openrouter.ai", "dashscope.aliyuncs.com", "open.bigmodel.cn", "ark.cn-beijing.volces.com", "qianfan.baidubce.com", "api.minimax.io", "api.minimaxi.com" ] } ``` ### Technical Analysis The launcher treats forwarded arguments as opaque strings. Validation only limits argument length and rejects selected control characters; it does not parse options or enforce the network-domain policy declared in `config.json`. Consequently, a `--base-url` option can designate a host outside the listed provider ...[truncated 1781 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (18)

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · README.md (reported line 110)May include surrounding context.

md
# MiniMax
export MINIMAX_API_KEY="..."
markdown-ai-rewrite rewrite -i input.md -o out.md -p minimax -m MiniMax-M2.1 -s casual

# DeepSeek
export DEEPSEEK_API_KEY="..."

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · README.md (reported line 119)May include surrounding context.

Azure OpenAI

export AZURE_OPENAI_API_KEY="..." export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com" markdown-ai-rewrite rewrite -i input.md -o out.md -p azure-openai -m gpt-4o-mini

text

更多参数(`-t`、`--max-tokens`、`--preserve-length`、`-c`、`--minimax-base-url` 等)见 **`markdown-ai-rewrite rewrite --help`** 与 [SKILL.md](./SKILL.md)。

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The file's declared behavior and the analyzed wrapper behavior do not align, including references to unsupported or undeclared functionality such as a check-quota command. Behavior mismatches are dangerous because reviewers and users may trust the metadata while the actual skill performs different actions, which undermines informed consent and security review.

Content

No source excerpt is available for this finding.

External Model or Provider Selection

High
Category
Excessive Agency
Confidence
90% confidence
Finding

Skill selects an external model or provider that may use a different account or billing plan than the operator expects. Undisclosed model switches can cause unexpected cost or quota consumption.

Content

Scanner excerpt · SKILL.md (reported line 223)May include surrounding context.

MiniMax(需 npm install openai)

export MINIMAX_API_KEY="..." md-rewrite rewrite -i input.md -o out.md -p minimax --rewrite -m MiniMax-M2.1 -s casual

text

### 图片生成

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README explicitly promotes sending Markdown content to multiple third-party AI providers for rewriting, but it does not warn users that document contents may leave their environment and be processed by external services. In a skill intended for document transformation, this creates a real privacy and data-governance risk, especially if users submit confidential notes, credentials, proprietary docs, or personal data.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · README.md (reported line 72)May include surrounding context.

md
| GLM | `GLM_API_KEY` |
| 豆包 | `DOUBAO_API_KEY` |
| 文心 | `WENXIN_API_KEY` |
| MiniMax | `MINIMAX_API_KEY`(可选 `MINIMAX_BASE_URL`,默认 `https://api.minimaxi.com/v1`) |

在 **Claw Hub** 中配置一次后,各 Skill 可共享同一环境变量。

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill advertises shell-based commands (npm install, md-rewrite, export ...) but does not declare any permissions or allowed-tools scope. In an agent environment, missing tool scoping can let the skill invoke broader shell capabilities than users expect, increasing the chance of unintended command execution or misuse.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

The skill is designed to send data to external AI/video/image providers, and the presence of configurable external endpoints confirms network transmission. In this context, the risk is not the URL itself but the fact that user content and prompts may be transmitted off-platform, potentially including sensitive information.

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
KLING_API_KEY: "可灵 API Key(视频生成 --video-provider kling)"
      RUNWAY_API_KEY: "Runway API Key(视频生成 --video-provider runway)"
      SHARED_OPENAI_KEY: "可选:内置共享 OpenAI Key 场景使用,见下文"
      MINIMAX_BASE_URL: "可选:MiniMax API Base URL,默认 https://api.minimaxi.com/v1"
tags:
  - markdown
  - ai

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill describes rewriting and media-generation workflows using third-party AI providers but does not clearly warn that Markdown content, prompts, and possibly embedded text may be transmitted to external services. This creates a data exposure risk, especially if users process sensitive documents without understanding that content leaves the local environment.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The documented MINIMAX_BASE_URL override allows content to be routed to an external endpoint, which can increase exposure if users point it to untrusted infrastructure. Combined with AI processing, this creates a clear external transmission path for document contents and prompts.

Content

Scanner excerpt · SKILL.md (reported line 156)May include surrounding context.

md
| `KLING_API_KEY` | `--video-provider kling`(可灵视频生成) |
| `RUNWAY_API_KEY` | `--video-provider runway`(Runway 视频生成) |
| `AZURE_OPENAI_ENDPOINT` | `azure-openai` 可选 endpoint(也可用 `--base-url`) |
| `MINIMAX_BASE_URL` | 可选;默认 `https://api.minimaxi.com/v1`,可按 MiniMax 文档覆盖 |
| `SHARED_OPENAI_KEY` | 可选;仅在 **未传 `apiKey`** 且代码里允许使用共享 Key 时由库内部使用(需配合 `QuotaManager` 等逻辑,见包内 README);**常规 CLI 用法请直接设置上述各厂商 Key。** |

---

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill is configured with autoInvoke set to true but the config does not define any trigger scope, matching constraints, or user-consent gate. That can cause the skill to activate unexpectedly on Markdown-related contexts and initiate networked AI actions using configured API keys, increasing the chance of unintended data exposure or unreviewed content modification.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
72% confidence
Finding

The skill declares write access to a persistent directory under ~/.markdown-ai-rewriter/, which enables session or artifact persistence across runs. In the context of a network-enabled rewriting tool that may process sensitive Markdown and use multiple API keys, persistent local storage can retain prompts, outputs, tokens, or metadata that later become accessible to other local processes or users.

Content

Scanner excerpt · config.json (reported line 67)May include surrounding context.

json
"audit": "https://github.com/sipingme/markdown-ai-rewriter/blob/main/src/index.ts"
    },
    "verification": {
      "command": "md-rewrite --version",
      "expectedOutput": "1.2.5"
    }
  },

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest description says the skill supports Markdown AI rewriting plus image, video, and music generation, but the implemented interface allow-lists only two subcommands: 'rewrite' and 'check-quota'. The code contains no paths exposing media-generation features, and even 'check-quota' is explicitly reported as unavailable in this version.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The README shows normal usage that writes rewritten content to an output file, but it does not clearly warn users that generated content can overwrite intended destinations, replace prior drafts, or alter meaning/format in ways that require review. This is a safety/usability issue rather than code execution, but in content pipelines it can still cause data loss or accidental publication of unwanted edits.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The manifest description and the entire skill documentation are presented in Chinese, which imposes a specific language on users without indicating that other languages are available. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale limitation is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest contains user-facing natural-language descriptions such as 重写 Markdown 文件 and 显示使用帮助和 API 配置方式, which imply a fixed language choice. Because there is no indication that the user can opt into Chinese or that the skill is intentionally limited to a Chinese-language audience, this may violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The user-facing natural-language content in this script is entirely Chinese, including the success message, feature descriptions, configuration guidance, and quick-start instructions. Under the policy, forcing a specific language without offering a language or locale choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The comments claim module resolution is restricted to standard node_modules roots, but the resolver also searches __dirname/../node_modules and process.cwd()/node_modules. In a skill execution context, allowing resolution from the current working directory can let a local attacker or compromised workspace supply a malicious 'markdown-ai-rewriter' package that is then imported and executed in-process.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.