Back to skill

Security audit

Md Wechat

Security checks for vulnerabilities and agentic risk

Overview

This is a real Markdown-to-WeChat converter, but normal use can automatically install packages and run remote browser code, so it needs review before installation.

Install only if you are comfortable with a document formatting tool that can install npm or pip dependencies and render diagrams through a headless browser. Prefer running it in an isolated environment, install dependencies yourself from reviewed lockfiles, use --no-auto-install, avoid untrusted Markdown or extracted HTML configs, and be cautious with Mermaid content because it loads remote JavaScript with the browser sandbox disabled.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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 (4)

T08 · Insecure Dependencies

Warning
Location
scripts/convert.js:872
Finding

Automatic npm Dependency Installation During Document Conversion

Content
View full analysis
0) { console.log(chalk.cyan(`[INFO] Detected missing dependencies: ${missing.join(', ')}`)); console.log(chalk.cyan('[INFO] Installing dependencies...')); const { execSync } = await import('child_process'); try { execSync(`npm install ${missing.join(' ')}`, { stdio: 'inherit' }); console.log(chalk.green('[OK] Dependency installation completed')); } catch (e) { console.error(chalk.red(`[ERROR] Dependency installation failed: ${e.message}`)); process.exit(1); } } } ``` The installation function is invoked by default from the command-line action unless the user supplies `--no-auto-install`: ```javascript if (options.autoInstall !== false) { await ensureDependencies(); } ``` ### Technical Analysis The normal conversion workflow automatically invokes `npm install` when dependencies are considered missing. Package installation can execute package lifecycle scripts with the privileges of the user running the converter. This behavior expands a Markdown conversion operation into a software-installation and code-execution operation. The package names are defined internally, so no direct shell-command injection through the `missing` array was identified. However, the packages are installed without an explicit version in this command. The project also uses semver ranges in `package.json`, and dependency resolution relies on an external package registry or configured mirror. This ...[truncated 1190 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/convert.py:21
Finding

Automatic pip Package Installation Triggered by Markdown Content

Content
View full analysis
bool: """ Automatically install a Python package. """ try: print(f'[INFO] Installing dependency: {package_name}...') result = subprocess.run( [sys.executable, '-m', 'pip', 'install', package_name], capture_output=True, text=True, timeout=120 ) if result.returncode == 0: print(f'[OK] {package_name} installed successfully') return True else: print(f'[WARN] Failed to install {package_name}: {result.stderr}') return False except subprocess.TimeoutExpired: print(f'[WARN] Installation timed out: {package_name}') return False except Exception as e: print(f'[WARN] Installation error for {package_name}: {e}') return False ``` The conversion path invokes dependency installation based on detected Markdown features: ```python if self.auto_install: required_features = self._detect_required_features(markdown_text) if required_features: status = ensure_dependencies(required_features) HAS_MARKDOWN = status.get('markdown', False) HAS_PYGMENTS = status.get('pygments', False) ``` For example, mathematical notation can cause `matplotlib` to be installed, while code blocks and complex Markdown can cause other packages to be installed. ### Technical Analysis The Python fallback treats document features as triggers for package installation. Consequently, untrusted Markdown can influence whether the process downloads and installs external software. The subprocess uses an argument array rather than a shell, and the package names passed by the current feature-detection l ...[truncated 1477 chars]
Remediation
View remediation

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/convert.js:285
Finding

Mutable Remote Mermaid Payload Executed in an Unsandboxed Browser

Content
View full analysis
`); const svg = await page.$eval('#container', async (container, code) => { const { svg } = await mermaid.render('mermaid-svg', code); container.innerHTML = svg; return container.innerHTML; }, code); return `
${svg}
`; } ``` ### Technical Analysis The converter loads Mermaid JavaScript directly from: ```text https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js ``` The URL does not pin an exact Mermaid version and does not provide Subresource Integrity metadata. The effective code executed during conversion can therefore change after the Skill package has been reviewed. At the same time, Puppeteer is launched with both `--no-sandbox` and `--disable-setuid-sandbox`. Disabling Chromium's sandbox removes an important containment boundary for untrusted or compromised web content. Rendering Mermaid diagrams legitimately requires Mermaid logic, but retrieving mutable executable JavaScript at runtime and disabling the browser sandbox are not minimum-privilege requirements. A locally installed, exact-version library can provide the same functionality. ### Attack Path 1. A Markdown document contains a fenced `mermaid` block. 2. The converter reco ...[truncated 1090 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/convert.js:710
Finding

Untrusted Markdown HTML Is Written to Browser-Executable Output Without Sanitization

Content
View full analysis
WeChat Official Account Article ${katexCSS} ${css}
${wordCountInfo} ${content}
`; ``` No sanitizer or raw-HTML prohibition is applied between `marked.parse` and the output sink. ### Technical Analysis Markdown parsers commonly preserve raw HTML unless the caller explicitly sanitizes or disables it. The converter does not apply an HTML allowlist before writing the generated document. An attacker-controlled Markdown file can therefore include active HTML such as script elements, event-handler attributes, iframes, active SVG, forms, or externally loaded tracking resources. The resulting file is intended to be opened in a browser for copying into the WeChat editor, making browser execution a foreseeable part of the ...[truncated 1677 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (50)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is ներկայացված as a Markdown-to-WeChat formatter, but the documented behavior also includes HTML style extraction, Markdown feature analysis, and generation of configuration JSON from local files. This mismatch is dangerous because it broadens the effective data-access and processing scope beyond user expectations, which can lead to overcollection of local content or execution of workflows the user did not intend to authorize.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/convert.js article.md --no-auto-install

Known Vulnerable Dependency: basic-ftp==5.2.0 — 4 advisory(ies): GHSA-6v7q-wjvx-w8wg (basic-ftp: Incomplete CRLF Injection Protection Allows Arbitrary FTP Command Exe); CVE-2026-39983 (basic-ftp has FTP Command Injection via CRLF); CVE-2026-41324 (basic-ftp vulnerable to denial of service via unbounded memory consumption in Cl) +1 more

High
Category
Supply Chain
Confidence
92% confidence
Finding

The lockfile includes basic-ftp 5.2.0, which is reported vulnerable to FTP command injection and DoS conditions. In this skill, basic-ftp is only a transitive dependency pulled in through get-uri/proxy tooling used by Puppeteer’s browser download path, so exploitability depends on the application actually handling attacker-controlled FTP/PAC/proxy URLs; still, the vulnerable package is present and could become reachable in some environments.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
95% confidence
Finding

extract-zip 2.0.1 is present and is associated with symlink-based arbitrary file write/path traversal issues during archive extraction. Because this skill depends on Puppeteer, which may download and extract browser archives via install scripts, a compromised or attacker-influenced archive source could potentially write outside the intended extraction directory.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.1.0 — 2 advisory(ies): CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco); CVE-2026-42338 (ip-address has XSS in Address6 HTML-emitting methods)

High
Category
Supply Chain
Confidence
80% confidence
Finding

ip-address 10.1.0 is flagged for parsing inconsistencies and an XSS issue in HTML-emitting helpers. Here it is only a transitive dependency of socks/socks-proxy-agent under Puppeteer’s proxy stack, and there is no evidence from this file that the vulnerable HTML output or ambiguous IP parsing is directly exposed to untrusted input in the skill’s Markdown-to-WeChat use case.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
90% confidence
Finding

js-yaml 4.1.1 is present and has reported CPU consumption issues when parsing malicious YAML. This matters because Puppeteer depends on cosmiconfig, which can load YAML-based configuration files; if an attacker can supply or influence config files consumed in the execution environment, they may trigger denial of service.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ws==8.19.0 — 2 advisory(ies): CVE-2026-45736 (ws: Uninitialized memory disclosure); CVE-2026-48779 (ws: Memory exhaustion DoS from tiny fragments and data chunks)

High
Category
Supply Chain
Confidence
88% confidence
Finding

ws 8.19.0 is included through puppeteer-core and is flagged for memory disclosure and memory exhaustion issues. Since Puppeteer may communicate over WebSocket with browser instances, a reachable attacker-controlled endpoint or malicious intermediary could potentially abuse these flaws, though the Markdown conversion context makes direct exposure less obvious than in a network-facing server.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script automatically installs missing npm packages by invoking npm install through execSync, which causes arbitrary code from package install lifecycle scripts to execute on the user's system. For a Markdown-to-WeChat formatter, silently expanding scope into package installation and shell execution is unnecessary and creates a significant supply-chain and local command-execution risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A markdown-to-WeChat formatting skill should not need the capability to install software on the host. Embedding dependency installation in a content-processing tool creates disproportionate power for the skill, exposing the environment to unreviewed external code and violating least privilege.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill description promises document conversion, but the implementation conditionally changes the runtime environment by importing/installing packages. That hidden side effect materially increases risk because untrusted document content can influence whether external code is fetched and executed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The main conversion flow inspects markdown content and automatically installs dependencies when certain syntax is detected. This makes hostile or crafted input capable of triggering network/package-management actions, which is far more dangerous than ordinary formatting and creates a content-to-code-supply-chain bridge.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/convert.py (reported line 1102)May include surrounding context.

python
styles = match.group(2).strip()
            rules[selector] = styles
        
        return rules
    
    def _wrap_html(self, content: str) -> str:
        """包装为完整 HTML 文档"""

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README advertises 'automatic dependency installation' for a Node.js CLI tool, which can lead users to execute package installation actions without fully understanding that arbitrary install-time scripts from dependencies may run. In the context of an agent skill or automation workflow, this increases supply-chain risk because dependency resolution and install hooks may execute code from third-party packages or compromised transitive dependencies.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill document describes behaviors that require file reads, file writes, and shell execution, but it does not declare any explicit tool scope such as permissions or allowed-tools. This is dangerous because an agent may invoke the skill with broader ambient privileges than users expect, increasing the chance of unintended local file access or command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill promotes automatic dependency installation via npm install without clearly stating that npm may execute package lifecycle scripts and modify the local environment. This is dangerous because running package installation in response to document conversion can trigger unreviewed code execution, network access, filesystem changes, and supply-chain compromise through malicious or compromised dependencies.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The Mermaid rendering path loads mermaid.min.js from a public CDN at runtime, and the generated HTML also links KaTeX CSS from jsDelivr. This introduces external network dependency, leaks usage metadata, and exposes rendering behavior to CDN compromise or unexpected remote content changes, which exceeds the expected offline/local behavior of a document formatting skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The tool performs automatic dependency installation without prior confirmation, meaning a normal conversion request can unexpectedly trigger package downloads and execution of installer scripts. In a CLI utility whose stated purpose is document conversion, this violates least surprise and meaningfully increases the chance of unwanted code execution or environment modification.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
98% confidence
Finding

The skill invokes pip install at runtime via subprocess.run, which allows a document-conversion workflow to mutate the host environment and fetch code from external package sources. In this skill’s context, that behavior is unnecessary for a pure formatter and can be triggered based on input content, increasing supply-chain and environment-tampering risk.

Content

Scanner excerpt · scripts/convert.py (reported line 32)May include surrounding context.

python
"""
    try:
        print(f'[INFO] 正在安装依赖: {package_name}...')
        result = subprocess.run(
            [sys.executable, '-m', 'pip', 'install', package_name],
            capture_output=True,
            text=True,

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/convert.js:46

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/convert.js:309