Back to skill

Security audit

Mermaid Image Export

Security checks for vulnerabilities and agentic risk

Overview

This skill does export Mermaid diagrams, but it also ships unsafe setup guidance and a batch script pattern that can run unintended local commands.

Install only if you are comfortable reviewing and running shell-based developer tooling. Prefer a local, pinned mermaid-cli dependency over global npm install, avoid the curl/wget pipe-to-shell instructions, do not use the batch_export.sh wrapper with untrusted filenames or arguments, and run PDF/browser rendering in an isolated low-privilege environment if possible.

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)

T03 · Remote Payload Retrieval and Execution

Error
Location
references/troubleshooting.md:53
Finding

Unverified Remote Installation Scripts Are Piped Directly into Shells

Content
View full analysis

Vulnerability Details

File Location: references/installation.md:172; references/troubleshooting.md:53,79
Vulnerability Type: Remote payload retrieval and execution
Risk Level: High

Vulnerable Code

references/installation.md:172:

bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

references/troubleshooting.md:53:

bash
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -

references/troubleshooting.md:79:

bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

Technical Analysis

These instructions download shell programs from external services and immediately execute the received content without signature verification, checksum validation, or local inspection. The effective code can therefore change after the Skill has been reviewed.

The NVM URL refers to a versioned path on the project's GitHub repository, which reduces accidental version drift, but the downloaded content is still executed without cryptographic verification. Compromise of the repository, maintainer account, hosting infrastructure, TLS trust chain, or local network trust configuration could replace the response.

The NodeSource command has a greater impact because it pipes the response into sudo -E bash. This executes the remote response with root privileges while preserving selected caller environment state. Installing Node.js is ancillary setup and does not require an image-export Skill to retrieve and directly execute mutable privileged shell code.

Attack Path

  1. An attacker compromises an upstream repository, account, CDN, DNS route, or other delivery component.
  2. The attacker modifies the remote response to include malicious shell commands.
  3. A user follows the installation or troubleshooting documentation.
  4. curl writes the attacker-controlled response directly to bash.
  5. The NVM payload ...[truncated 903 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove all curl | bash and curl | sudo bash installation instructions.
  • Prefer Node.js packages supplied by the operating system or a documented package manager with repository signature validation.
  • If an upstream installer must be used:
    1. Pin an immutable release and exact artifact.
    2. Download it to a local file.
    3. Verify a maintainer-published cryptographic signature or pinned SHA-256 digest.
    4. Inspect the script before execution.
    5. Run it without sudo unless a reviewed operation specifically requires elevation.
  • Do not preserve the calling environment when elevating privileges unless each retained variable is necessary and validated.
  • Document the expected artifact digest and trusted signing key.
  • Separate optional environment setup from the core diagram-export workflow.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/batch_export.sh:160
Finding

Shell Command Injection Through Dynamically Constructed eval Command

Content
View full analysis

Vulnerability Details

File Location: scripts/batch_export.sh:160-187
Vulnerability Type: Shell command injection
Risk Level: High

Vulnerable Code

bash
export_diagram() {
    local input_file="$1"
    local output_file="$2"
    
    if [ "$VERBOSE" = "true" ]; then
        echo -e "${BLUE}Exporting: $input_file -> $output_file${NC}"
    fi
    
    # Build command
    local cmd="$MERMAID_CMD"
    cmd+=" -i \"$input_file\""
    cmd+=" -o \"$output_file\""
    cmd+=" -t \"$THEME\""
    cmd+=" -b \"$BACKGROUND\""
    cmd+=" -s \"$SCALE\""
    
    # For PDF, we need Puppeteer config
    if [ "$FORMAT" = "pdf" ]; then
        local config_file="$(mktemp)"
        cat > "$config_file" << EOF
{
  "args": ["--no-sandbox", "--disable-setuid-sandbox"],
  "headless": "new"
}
EOF
        cmd+=" -p \"$config_file\""
    fi
    
    # Run command
    if eval "$cmd" 2>/dev/null; then

Technical Analysis

The script concatenates command-line arguments into one shell command string and executes the result with eval. eval causes the shell to parse the generated text for a second time. Shell metacharacters, command substitutions, quote delimiters, redirections, and separators contained in interpolated values can consequently become executable syntax.

Potentially attacker-influenced values include MERMAID_CMD, input_file, output_file, THEME, BACKGROUND, and SCALE. Several are accepted directly from command-line options or filenames. The script adds double quotes as text, but this is not a reliable defense because a value containing a double quote can terminate the generated quoted argument before the second parsing pass.

For example, a crafted theme value containing a closing quote, command separator, and shell command can break out of the generated -t argument when eval reparses the string.

Attack Path

  1. An attacker controls an option p ...[truncated 1139 chars]
Remediation
View remediation

Remediation Suggestions

  • Remove eval completely.
  • Represent the executable and every argument as separate Bash array elements:
bash
cmd=(mmdc
    -i "$input_file"
    -o "$output_file"
    -t "$THEME"
    -b "$BACKGROUND"
    -s "$SCALE"
)

if [ "$FORMAT" = "pdf" ]; then
    cmd+=(-p "$config_file")
fi

"${cmd[@]}"
  • Do not accept an arbitrary command expression through --mermaid-cmd. Offer a constrained selection such as mmdc or npx --no-install mmdc, represented internally as arrays.
  • Validate the theme against the supported allowlist.
  • Validate scale as a bounded positive numeric value.
  • Validate background values according to the accepted Mermaid CLI color syntax.
  • Add regression tests using filenames and arguments containing spaces, quotes, semicolons, command substitutions, and newlines.
  • Run export jobs under a minimally privileged account without unnecessary secrets in the environment.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/export_mermaid_image.py:134
Finding

Chromium Sandbox Is Disabled Automatically During PDF Export

Content
View full analysis

Vulnerability Details

File Location: scripts/export_mermaid_image.py:134-147; also present in scripts/batch_export.sh:174-181 and assets/examples/config_example.json:51-52
Vulnerability Type: Unsafe browser security configuration
Risk Level: Medium

Vulnerable Code

scripts/export_mermaid_image.py:134-147:

python
def create_puppeteer_config(width: Optional[int], height: Optional[int]) -> str:
    """Create Puppeteer config for PDF export."""
    config = {
        "args": ["--no-sandbox", "--disable-setuid-sandbox"],
        "headless": "new"
    }
    
    if width or height:
        config["defaultViewport"] = {}
        if width:
            config["defaultViewport"]["width"] = width
        if height:
            config["defaultViewport"]["height"] = height
    
    return json.dumps(config, indent=2)

scripts/batch_export.sh:174-181:

bash
if [ "$FORMAT" = "pdf" ]; then
    local config_file="$(mktemp)"
    cat > "$config_file" << EOF
{
  "args": ["--no-sandbox", "--disable-setuid-sandbox"],
  "headless": "new"
}
EOF

assets/examples/config_example.json:51-52:

json
"--no-sandbox",
"--disable-setuid-sandbox"

Technical Analysis

Chromium uses process sandboxing to restrict the filesystem, process, and operating-system access available after compromise of a renderer process. Passing both --no-sandbox and --disable-setuid-sandbox removes this isolation.

The Python exporter generates this configuration automatically for PDF output rather than limiting it to an explicitly isolated container environment. Mermaid diagrams, custom CSS, configuration files, fonts, and browser-rendered resources may be attacker-controlled in shared repositories or automated documentation pipelines. If such content triggers a vulnerability in Chromium, Mermaid, Puppeteer, or a rendering dependency, disabling the browser sandbox materially inc ...[truncated 1331 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove --no-sandbox and --disable-setuid-sandbox from the default Puppeteer configuration.
  • Allow Chromium to use its normal sandbox on supported hosts.
  • If a particular container cannot support the sandbox, require an explicit opt-in flag with a prominent warning.
  • For unsandboxed operation, enforce compensating controls:
    • Run as a dedicated unprivileged user.
    • Use a read-only root filesystem.
    • Mount only required input and output directories.
    • Drop Linux capabilities.
    • Apply seccomp and mandatory access-control profiles.
    • Disable or restrict network access.
    • Do not expose credentials or sensitive host directories.
  • Treat diagrams, CSS, Mermaid configuration, fonts, and referenced resources as untrusted inputs.
  • Keep Chromium, Puppeteer, Mermaid, and mermaid-cli pinned and promptly patched.
  • Remove the unsafe flags from the example configuration so users do not copy them into ordinary environments.

T08 · Insecure Dependencies

Warning
Location
scripts/export_mermaid_image.py:28
Finding

Unpinned npm Installation and Ambiguous npx Package Resolution

Content
View full analysis

Vulnerability Details

File Location: scripts/export_mermaid_image.py:28-33; related installation instructions appear in SKILL.md:69-71 and package.json:39
Vulnerability Type: Insecure third-party dependency execution
Risk Level: Medium

Vulnerable Code

scripts/export_mermaid_image.py:28-33:

python
# Try npx mmdc
try:
    subprocess.run(["npx", "mmdc", "--version"], capture_output=True, check=True)
    return "npx mmdc"
except (subprocess.CalledProcessError, FileNotFoundError):
    pass

SKILL.md:69-71:

bash
npm install -g @mermaid-js/mermaid-cli

package.json:39:

json
"installation": "npm install -g @mermaid-js/mermaid-cli",

Technical Analysis

The fallback check invokes npx mmdc rather than explicitly invoking a lockfile-installed @mermaid-js/mermaid-cli binary with package installation disabled. Depending on the local npm/npx version and environment, npx can resolve or retrieve packages when the expected executable is absent.

The documented installation command also installs the latest registry-selected version globally without a pinned version or project lockfile. npm package installation may execute package lifecycle scripts with the privileges of the installing user. A compromised maintainer account, malicious newly published release, registry compromise, or resolution mismatch can therefore turn dependency setup into local code execution.

The audited files do not establish that the current Mermaid package is malicious. The issue is that dependency identity and version are not reproducibly constrained.

Attack Path

  1. The expected local or global mmdc binary is unavailable, or a user follows the documented global installation command.
  2. npx resolves registry content, or npm selects the current latest release of the package and its transitive dependencies.
  3. An attacker has compromised a selected package, release, maintain ...[truncated 805 chars]
Remediation
View remediation

Remediation Suggestions

  • Declare @mermaid-js/mermaid-cli as a project dependency pinned to a reviewed version.
  • Commit and enforce an npm lockfile with integrity hashes.
  • Install dependencies with a reproducible command such as npm ci.
  • Invoke the local executable directly, for example node_modules/.bin/mmdc.
  • If npx is retained, use npx --no-install mmdc so dependency checks cannot silently download packages.
  • Replace global installation guidance with a local, lockfile-backed setup.
  • Review transitive dependencies and enable automated vulnerability and integrity monitoring.
  • In CI, install dependencies under a non-privileged account and avoid exposing deployment credentials during dependency installation.
  • Where operationally feasible, disable lifecycle scripts during initial acquisition and explicitly enable only reviewed build steps.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (81)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill is presented as an image export utility, but its documented behavior includes dependency checking, package installation, and troubleshooting flows that can execute system-modifying commands. This mismatch is dangerous because users or agents may trust it as a simple renderer while it also performs broader shell actions, which weakens informed consent and increases the chance of unexpected package installation or setup execution.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Piping the output of wget directly into sudo apt-key add - is a classic command-chaining hazard because untrusted remote content is immediately consumed by a privileged trust-establishment command. This amplifies supply-chain compromise risk and removes safe inspection points.

Content

Scanner excerpt · references/installation.md (reported line 80)May include surrounding context.

md
sudo apt install chromium-browser

# Or install Google Chrome
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt update
sudo apt install google-chrome-stable

Chaining Abuse

High
Category
Tool Misuse
Confidence
75% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · references/installation.md (reported line 81)May include surrounding context.

Or install Google Chrome

wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list sudo apt update sudo apt install google-chrome-stable

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

curl -o- ... | bash chains remote content retrieval directly into a shell interpreter, enabling arbitrary code execution with no integrity validation. In an installation guide, this is especially risky because users are encouraged to copy-paste it verbatim, increasing the likelihood of exploitation if the source is compromised.

Content

Scanner excerpt · references/installation.md (reported line 172)May include surrounding context.

sudo chown -R $USER:$USER ~/.config

Or use node version manager

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash nvm install node

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This command chains remote content fetch directly into a privileged shell, which is one of the highest-risk patterns in operational documentation. A single upstream compromise or MITM event would grant immediate root-level code execution on the host.

Content

Scanner excerpt · references/troubleshooting.md (reported line 53)May include surrounding context.

Using package manager:

Ubuntu: Use nodesource PPA

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt install nodejs

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Piping a remote installer directly into bash allows arbitrary code execution from the network with no integrity verification or review. Even without sudo, this can compromise the user account, developer environment, tokens, and source code present on the machine.

Content

Scanner excerpt · references/troubleshooting.md (reported line 79)May include surrounding context.

sudo chown -R $USER:$USER ~/.config

Or use nvm to avoid permission issues

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash nvm install node

text

Chaining Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Piping a downloaded key into sudo apt-key add - chains external content into a privileged trust-management command. Although less severe than piping into a shell, it still modifies system trust based on network content and can facilitate malicious package installation.

Content

Scanner excerpt · references/troubleshooting.md (reported line 137)May include surrounding context.

md
sudo apt install chromium-browser

# Or install Google Chrome
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
sudo apt update
sudo apt install google-chrome-stable

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/usage.md (reported line 240)May include surrounding context.

diagrams: $(IMAGES)

clean: rm -f images/.png images/.svg images/*.pdf

text

### 5. Dynamic Diagram Generation

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
96% confidence
Finding

Tool execution through subprocess.run with shell=True is a high-risk pattern because shell metacharacters, path manipulation, or future variable interpolation can transform benign checks into arbitrary command execution. In the context of an agent skill that may evolve or be reused, this makes the helper unnecessarily dangerous compared with safer direct process invocation.

Content

Scanner excerpt · scripts/install_mermaid_cli.py (reported line 18)May include surrounding context.

python
def run_command(cmd):
    """Run a command and return (success, output)."""
    try:
        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True, timeout=10
        )
        return result.returncode == 0, result.stdout.strip()

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file presents all instructions and usage guidance exclusively in Chinese, including the title, headings, and explanatory text. Under the language/locale policy rule, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly instructs use of shell commands such as npm install -g and Python scripts, but it declares no permissions or allowed-tools scope. That creates an authorization gap where an agent may invoke shell capabilities without an explicit least-privilege contract, increasing the risk of unintended command execution or environment modification.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · assets/examples/config_example.json (reported line 113)May include surrounding context.

json
"removeRasterImages",
        "removeUselessDefs",
        "cleanupNumericValues",
        "cleanupListOfValues",
        "convertColors",
        "removeUnknownsAndDefaults",
        "removeNonInheritableGroupAttrs",

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 29)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 30)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 77)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 82)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 83)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 168)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 169)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 281)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/installation.md (reported line 282)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/troubleshooting.md (reported line 54)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/troubleshooting.md (reported line 75)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/troubleshooting.md (reported line 76)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/troubleshooting.md (reported line 134)May include surrounding context.

Ubuntu/Debian

bash
sudo apt update
sudo apt install nodejs npm

Static analysis

No suspicious patterns detected.