Back to skill

Security audit

Mermaid Workflow Skill

Security checks for vulnerabilities and agentic risk

Overview

This Mermaid diagram skill is mostly aligned with its stated purpose, but it needs review because it weakens browser sandboxing and can execute an unpinned npm package.

Review before installing. Prefer a pinned, locally installed Mermaid CLI with a lockfile, remove or disable the automatic npx fallback, and avoid Chromium --no-sandbox rendering unless inside a disposable isolated container or VM. Treat Mermaid files from others as untrusted, back up Markdown files before insertion, and avoid sudo/root for normal operation.

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

T08 · Insecure Dependencies

Warning
Location
scripts/convert_mermaid.py:96
Finding
Unpinned Mermaid CLI Package May Be Downloaded and Executed Through npx<![CDATA[ ## Vulnerability Details **File Location**: `scripts/convert_mermaid.py:96-101` **Vulnerability Type**: Unpinned third-party dependency execution **Risk Level**: Medium ### Vulnerable Code ```python # 尝试使用npx print("尝试使用npx...") cmd[0] = 'npx' cmd.insert(1, '@mermaid-js/mermaid-cli') result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) ``` The same unversioned dependency is recommended in `README.md:17-20` and `SKILL.md:52-55`: ```bash npm install -g @mermaid-js/mermaid-cli # Or use npx npx @mermaid-js/mermaid-cli --version ``` ### Technical Analysis The conversion script falls back to executing `@mermaid-js/mermaid-cli` through `npx` when the initial `mmdc` conversion fails. No exact package version, lockfile, or integrity value constrains the artifact that may be executed. Depending on the local npm cache and npx configuration, npx can retrieve the currently published package and execute its package code. This makes the effective dependency capable of changing after the Skill has been reviewed. The package name is the expected official scoped package, and no evidence indicates that it is currently malicious; the vulnerability is the absence of reproducible dependency pinning and the automatic execution behavior. The subprocess call uses an argument list rather than `shell=True`, so this is not shell-command injection. The risk instead arises from supply-chain trust placed in an unpinned remote package. ### Attack Path 1. An attacker compromises the upstream package, its publisher account, or the relevant package distribution channel. 2. A malicious or compromised release becomes the version resolved by the unversioned package specification. 3. A user follows the documented npx installation command, or an installed `mmdc` returns an error and triggers the script's npx fallback. 4. npx downloads or resolves the unpinned package. 5. Package installation or CLI code executes with the privileges of the user running the Sk ...[truncated 554 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin Mermaid CLI to a reviewed exact version, such as `@mermaid-js/mermaid-cli@X.Y.Z`. 2. Add a project-local `package.json` and committed lockfile generated by `npm ci`. 3. Invoke the locally installed locked binary rather than allowing npx to resolve a package dynamically. 4. Remove the automatic npx fallback. If the local binary fails, return an error and require an explicit dependency installation step. 5. Use npm integrity verification and review lockfile changes during dependency updates. 6. Run the renderer under a dedicated, unprivileged account or isolated container to limit the consequences of a compromised dependency. 7. Avoid running dependency installation or diagram conversion as root. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/convert_mermaid.py:32
Finding
Puppeteer Configuration Disables Chromium Sandbox Protections<![CDATA[ ## Vulnerability Details **File Location**: `scripts/convert_mermaid.py:32-39` **Additional Locations**: `quick_start.sh:51-56`, `quick_start_example/puppeteer-config.json:1-3`, `README.md:134-139`, `SKILL.md:64-69`, `examples/example_workflow.md:131-136` **Vulnerability Type**: Unsafe browser security configuration **Risk Level**: Medium ### Vulnerable Code ```python def create_puppeteer_config(config_path): """创建Puppeteer配置文件解决沙箱问题""" config = { "args": ["--no-sandbox", "--disable-setuid-sandbox"] } with open(config_path, 'w', encoding='utf-8') as f: json.dump(config, f, indent=2) ``` The quick-start workflow creates and then passes the same configuration to the renderer: ```bash cat > puppeteer-config.json << EOF { "args": ["--no-sandbox", "--disable-setuid-sandbox"] } EOF python3 ../scripts/convert_mermaid.py \ --input example_roadmap.mmd \ --output example_roadmap.png \ --puppeteer-config puppeteer-config.json ``` ### Technical Analysis The configuration supplies both `--no-sandbox` and `--disable-setuid-sandbox` to Chromium through Puppeteer. These flags disable Chromium's primary process-isolation controls. Mermaid rendering processes diagram definitions in a browser environment. If an attacker can influence an `.mmd` file and exploit a vulnerability in Mermaid, Chromium, Puppeteer, or another rendering component, disabling the sandbox removes an important containment boundary. A renderer vulnerability is still required for host code execution; Mermaid text alone is not shown by the audited code to provide direct operating-system command execution. The unsafe configuration is not merely documented as an exceptional workaround. It is generated by the conversion utility when requested, included as a project example, and used by the quick-start workflow. ### Attack Path 1. An attacker supplies or modifies a Mermaid `.mmd` file that will be rendered by the Skill. 2. The user invokes convers ...[truncated 1077 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox` from default and example configurations. 2. Configure the host so Chromium's supported sandbox can operate normally. 3. If sandboxing cannot be enabled, run rendering inside a hardened, disposable container or virtual machine with: - A non-root user - A read-only root filesystem - Only required project files mounted - No secrets or credential directories mounted - Restricted network access - Linux capabilities removed - Resource and process limits 4. Treat externally supplied Mermaid files as untrusted input. 5. Keep Mermaid CLI, Puppeteer, and Chromium pinned and promptly patched. 6. Make any sandbox-disabled mode an explicit opt-in accompanied by a prominent security warning rather than a quick-start default. 7. Reject execution as root when sandbox protections are disabled. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (29)

Missing User Warnings

High
Confidence
97% confidence
Finding
The README recommends disabling the browser sandbox via Puppeteer config without prominently warning that this removes a major security boundary. Because Mermaid rendering relies on a browser engine, disabling sandboxing can substantially increase host compromise risk if crafted diagram content, browser bugs, or untrusted assets are involved.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The natural-language instructions throughout the file are presented exclusively in Chinese, which can functionally force a language choice on users. The file does not offer an alternative language, opt-in behavior, or explain that the skill is intentionally region-specific, so this appears to violate the language/locale policy criterion.

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.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This markdown file instructs users to run `insert_to_md.py` to insert content into `report.md`, which is a file-write operation affecting user data. The README presents the command as routine usage but does not include any warning about modifying the target file, replacing placeholders, or recommending a backup/review before execution.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The README explicitly documents running an external CLI and pairing it with a Puppeteer configuration that disables Chromium sandbox protections. While invoking `mmdc` is aligned with the skill's stated purpose, normalizing sandbox disabling lowers isolation for browser-rendered content and increases the blast radius if Mermaid input or browser components are malicious.

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.

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.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The skill explicitly instructs users to configure Puppeteer/Chromium with `--no-sandbox` and `--disable-setuid-sandbox` to work around launch issues, but does not warn about the security tradeoff. Disabling the browser sandbox weakens a key containment boundary, making malicious Mermaid content, renderer bugs, or compromised dependencies more dangerous during rendering.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The document's headings, instructions, and examples are all presented in Chinese, which can amount to a forced language choice when no alternative language option or opt-in is provided. The file does not indicate that the skill is intentionally region-specific or that users may select another language.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### 问题3: 中文显示问题
```bash
# 安装中文字体(Ubuntu)
sudo apt-get install fonts-wqy-zenhei

# 或在mmdc命令中指定字体
mmdc --fontFamily "WenQuanYi Zen Hei"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### 问题3: 中文显示问题
```bash
# 安装中文字体(Ubuntu)
sudo apt-get install fonts-wqy-zenhei

# 或在mmdc命令中指定字体
mmdc --fontFamily "WenQuanYi Zen Hei"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
### 问题3: 中文显示问题
```bash
# 安装中文字体(Ubuntu)
sudo apt-get install fonts-wqy-zenhei

# 或在mmdc命令中指定字体
mmdc --fontFamily "WenQuanYi Zen Hei"
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The script's comments, prompts, and status messages are entirely in Chinese, including user-facing interaction such as the continuation prompt at L021. For a general quick-start skill, this imposes a specific language on users without opt-in or documented regional justification, which matches the language/locale policy violation criteria.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding
The script recommends running Mermaid CLI via npx without pinning a specific version, which can fetch whatever package version is current at execution time. This creates a supply-chain risk: a compromised upstream release or breaking change could lead to unexpected code execution or unsafe behavior on the user's machine.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The module docstring and all visible CLI messages are written in Chinese, which imposes a specific language on users. The file does not offer any language/locale option or indicate that this tool is intentionally limited to a Chinese-speaking or region-specific audience.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def check_mmdc_installed():
    """检查mmdc是否安装"""
    try:
        result = subprocess.run(['mmdc', '--version'], 
                              capture_output=True, text=True)
        if result.returncode == 0:
            version = result.stdout.strip()
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The generated Puppeteer config disables Chromium sandbox protections via --no-sandbox and --disable-setuid-sandbox. Because the tool renders potentially untrusted Mermaid input through a browser-based engine, removing sandbox isolation significantly increases the impact of any browser or renderer compromise, potentially enabling arbitrary code execution or host access.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print(f"执行命令: {' '.join(cmd)}")
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        
        if result.returncode == 0:
            print(f"✅ Mermaid图表已转换为PNG: {output_file}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding
The script explicitly falls back to invoking npx for @mermaid-js/mermaid-cli without a pinned version. That means code may be downloaded and executed at runtime from npm or another configured source, creating a meaningful supply-chain risk and making behavior non-reproducible and attacker-influenceable.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
cmd[0] = 'npx'
            cmd.insert(1, '@mermaid-js/mermaid-cli')
            
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
            if result.returncode == 0:
                print(f"✅ 使用npx转换成功: {output_file}")
                return True
Confidence
94% confidence
Finding
Falling back to npx @mermaid-js/mermaid-cli executes a package that is not pinned to a specific version, which can fetch and run whatever version is currently published or resolved in the environment. In a hostile or compromised registry, mirror, or local npm configuration, this creates a software supply-chain execution path that can lead to arbitrary code execution under the user's privileges.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code file contains natural-language docstrings and CLI help/output text entirely in Chinese, beginning with the module description. The policy allows locale constraints only when the skill offers opt-in choice or clearly documents a justified regional requirement, neither of which is present here.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This code writes directly back to the user-supplied Markdown file, replacing its contents in place. Although the script prints status messages after the fact, there is no confirmation prompt, backup step, or prior warning in comments/docstrings that the original file will be overwritten.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
In batch mode, the script rewrites the target Markdown file after replacing placeholders, which can alter substantial document content. The code logs completion afterward, but does not provide a prior warning, confirmation prompt, or inline documentation describing this overwrite behavior.

Static analysis

No suspicious patterns detected.