Back to skill

Security audit

Huo15 Flow Chart

Security checks for vulnerabilities and agentic risk

Overview

This diagram skill appears purpose-built, but it can automatically run unpinned external renderers and Docker/Chromium with weak sandboxing, so it needs review before use.

Use this only if you trust the publisher and can control the rendering environment. Prefer preinstalled, pinned renderer binaries; avoid the automatic npx and Docker fallbacks; do not render untrusted diagram source on a sensitive machine; and run it in a dedicated working directory because outputs are written to user-supplied paths.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/flowchart_render.py:82
Finding

Automatic Execution of Unpinned External Rendering Components

Content
View full analysis

Vulnerability Details

File Location: scripts/flowchart_render.py:82-94
Vulnerability Type: Automatic retrieval and execution of mutable third-party components
Risk Level: High

Vulnerable Code

python
def _find_mmdc() -> Optional[list]:
    if shutil.which("mmdc"):
        return ["mmdc"]
    if shutil.which("npx"):
        return ["npx", "-y", "@mermaid-js/mermaid-cli"]
    if shutil.which("docker"):
        return [
            "docker", "run", "--rm", "-u", f"{os.getuid()}:{os.getgid()}",
            "-v", f"{os.getcwd()}:/data",
            "minlag/mermaid-cli", "-"
        ]
    return None

Technical Analysis

When a locally installed mmdc executable is unavailable, the renderer automatically falls back to:

  1. npx -y @mermaid-js/mermaid-cli, which can retrieve and execute the current registry version without user confirmation or an exact version pin.
  2. The mutable Docker image minlag/mermaid-cli, which is referenced without a digest or immutable version.

Because neither dependency is pinned to a verified immutable artifact, the code executed during rendering may differ from the code that was reviewed. The -y option suppresses interactive confirmation, making package retrieval and execution automatic.

The Docker fallback additionally mounts the entire current working directory into the container as /data. A compromised container image could consequently read or modify files in that directory using the invoking user's UID and GID.

There is also a documentation discrepancy: the renderer module describes the Docker backend as ghcr.io/mermaid-js/mermaid-cli, while the implementation executes minlag/mermaid-cli. This makes it harder for users to accurately assess the component that will run.

Attack Path

  1. An attacker compromises a release of @mermaid-js/mermaid-cli, one of its transitive dependencies, the package registry response, or the mutable `mi ...[truncated 1159 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not automatically retrieve dependencies during normal rendering. Require users to install a reviewed renderer explicitly.
  2. If automatic retrieval remains supported, require an explicit opt-in flag and display the exact package or image that will be executed.
  3. Pin the npm package to an exact reviewed version, such as @mermaid-js/mermaid-cli@x.y.z, and use a lockfile where applicable.
  4. Pin container images by immutable digest rather than a mutable name or tag.
  5. Use the documented official image consistently and remove the discrepancy between documentation and implementation.
  6. Verify downloaded artifacts using trusted checksums, signatures, or provenance attestations.
  7. Mount only a dedicated temporary input/output directory into the container rather than the entire current working directory.
  8. Make container mounts read-only unless output writing is strictly necessary. Use separate read-only input and narrowly scoped writable output mounts.
  9. Run the container without network access, with dropped Linux capabilities, a read-only root filesystem, resource limits, and no-new-privileges.
  10. Document all direct and transitive dependency versions so installations can be reproduced and audited.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/flowchart_render.py:126
Finding

Chromium Sandbox Is Unconditionally Disabled During Mermaid Rendering

Content
View full analysis

Vulnerability Details

File Location: scripts/flowchart_render.py:126-130
Vulnerability Type: Unsafe browser-renderer configuration
Risk Level: Medium

Vulnerable Code

python
# 设置 puppeteer 的 no-sandbox 配置(常见 Linux CI 报错)
pup_cfg = Path(td) / "puppeteer.json"
pup_cfg.write_text(json.dumps({"args": ["--no-sandbox", "--disable-setuid-sandbox"]}))
cmd += ["-p", str(pup_cfg)]

Technical Analysis

Mermaid CLI uses Puppeteer and Chromium to process diagram content. The generated Puppeteer configuration always supplies both --no-sandbox and --disable-setuid-sandbox, removing major Chromium process-isolation controls.

The project also accepts raw Mermaid source and passes it to the renderer substantially unchanged. Consequently, untrusted diagram content may be processed by Chromium while its normal sandbox protection is disabled.

Disabling the sandbox does not independently establish arbitrary code execution. However, it materially increases the impact of a vulnerability in Chromium, Puppeteer, Mermaid CLI, or related rendering logic. If crafted content triggers a renderer vulnerability, the compromised rendering process has fewer barriers separating it from the invoking user's account and accessible host resources.

Attack Path

  1. An attacker supplies a malicious or specially crafted raw Mermaid input file.
  2. The user invokes the Skill to render the input as SVG, PNG, or PDF.
  3. The Skill creates a Puppeteer configuration that disables Chromium's sandbox and setuid sandbox.
  4. Mermaid CLI launches Chromium with those weakened security settings.
  5. The crafted input triggers an applicable vulnerability in Chromium or the rendering stack.
  6. Exploit code escapes the renderer process without needing to defeat Chromium's normal sandbox and executes with the renderer's effective user privileges.

This exploitation path is conditional on a separate vulnerability in the browser or renderi ...[truncated 654 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove --no-sandbox and --disable-setuid-sandbox from the default Puppeteer configuration.
  2. Ensure the host or container environment supports Chromium user namespaces or the setuid sandbox.
  3. If sandbox disabling is unavoidable in a specific CI environment, make it an explicit, prominently documented opt-in rather than the default.
  4. Reject sandbox disabling when the process runs as root or another privileged account.
  5. Process untrusted diagrams inside a dedicated container or sandbox with:
    • No network access.
    • No host project-directory mount.
    • A read-only root filesystem.
    • A dedicated unprivileged UID.
    • Dropped capabilities.
    • no-new-privileges.
    • Strict CPU, memory, process, and execution time limits.
    • Narrow temporary input and output directories.
  6. Pin and regularly update Chromium, Puppeteer, Mermaid CLI, and all transitive dependencies.
  7. Apply input-size and complexity limits to reduce exposure to renderer denial-of-service and parser vulnerabilities.
  8. Clearly distinguish trusted local diagram rendering from processing of untrusted raw Mermaid content.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill advertises extensive parsing, style, draw.io, and C4-specific behavior that the detected implementation apparently does not provide. This gap is dangerous because users and orchestrators may trust the skill to safely transform structured input while it may instead pass unvalidated source directly to downstream renderers or write arbitrary content verbatim, increasing injection and unsafe-processing risk.

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 247)May include surrounding context.

md
der/ship/deploy/rocket/bug/gear/shield/alarm 等 70+ 个,查完整列表见 [flowchart_core.py](scripts/flowchart_core.py) 中的 `_ICON_ALIASES`。

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares executable capabilities and external command usage patterns (shell, file output, environment access) but does not define any explicit tool scope or permissions boundaries. In an agent environment, this can enable over-broad execution authority, making command execution and file writes available in contexts far beyond simple diagram rendering.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The alias list is extremely broad, including generic terms like flowchart, diagram, mermaid, and draw.io, which can cause this skill to activate on many unrelated requests. When a skill with execution and file-write capability triggers too easily, it expands the attack surface and increases the chance of unsafe tool use in contexts where the user did not intend this skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The documented trigger list is ambiguous and lacks clear boundaries, so common requests for diagrams or architecture discussions may invoke the skill unnecessarily. In combination with shell-based renderers and file generation, ambiguous activation materially raises the likelihood of unintended execution paths and exposure to malicious user-supplied diagram source.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The architecture file uses Chinese-only titles and labels throughout, such as the title and component names, without indicating that the skill is region-specific or offering any language choice. This can violate language/locale policy when a skill implicitly requires a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The title is written entirely in Chinese ("火一五 Q2 产品路线图"), which indicates a fixed language choice in natural-language content. The file does not offer any language/locale choice or document a justified region-specific constraint, so this appears to violate the language/locale policy criterion.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The file’s title, labels, and note text are entirely in Chinese, and there is no indication that language selection is optional or that the skill is intentionally limited to a Chinese-only audience. Under the natural-language policy, forcing a specific language without user opt-in is a locale-policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The module docstring that documents common usage is entirely in Chinese, and the script continues to present user-facing help text in Chinese. This imposes a specific language on all users without offering an alternative locale or any opt-in mechanism, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The command description, epilog, and argument help strings are all presented only in Chinese, making the CLI effectively single-locale. Because there is no documented language selection or justification for a region-specific audience, this is a natural-language locale policy issue.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This file contains natural-language strings intended for users or developers, including the top-level module description and later runtime messages, exclusively in Chinese. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The natural-language documentation in this code is entirely in Chinese, including user-facing error and usage text later in the file. That imposes a specific language/locale on users without offering a choice or documenting that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Mermaid backend discovery permits fallback to npx -y @mermaid-js/mermaid-cli and to docker run, which can trigger network-based package/image retrieval and execution at runtime. In a skill that should only render diagrams, this expands trust boundaries substantially: attacker-influenced execution may depend on PATH resolution, package registry content, Docker daemon access, and host-directory mounting, increasing supply-chain and container escape exposure.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/flowchart_render.py (reported line 132)May include surrounding context.

python
pup_cfg.write_text(json.dumps({"args": ["--no-sandbox", "--disable-setuid-sandbox"]}))
        cmd += ["-p", str(pup_cfg)]
        try:
            subprocess.run(cmd, check=True, capture_output=True, text=True)
        except subprocess.CalledProcessError as e:
            raise RuntimeError(
                f"mmdc 渲染失败:\nSTDOUT: {e.stdout}\nSTDERR: {e.stderr}"

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/flowchart_render.py (reported line 260)May include surrounding context.

python
pup_cfg.write_text(json.dumps({"args": ["--no-sandbox", "--disable-setuid-sandbox"]}))
        cmd += ["-p", str(pup_cfg)]
        try:
            subprocess.run(cmd, check=True, capture_output=True, text=True)
        except subprocess.CalledProcessError as e:
            raise RuntimeError(
                f"mmdc 渲染失败:\nSTDOUT: {e.stdout}\nSTDERR: {e.stderr}"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Falling back to docker run ... plantuml/plantuml -pipe gives the skill the ability to execute containerized code outside the minimal scope needed for a document-rendering helper. This is especially risky because the skill processes untrusted diagram source, and Docker access often implies broad host impact; even without a direct exploit in this file, automatic container execution materially increases attack surface and supply-chain risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/flowchart_render.py (reported line 188)May include surrounding context.

python
src.write_text(source, encoding="utf-8")
        full_cmd = list(cmd) + extra_flags + [fmt, "-o", str(out.parent.absolute()), str(src)]
        try:
            subprocess.run(full_cmd, check=True, capture_output=True, text=True)
        except (subprocess.CalledProcessError, FileNotFoundError) as e:
            # 保底:把源码落盘,调用方可以复制到在线编辑器
            fallback = out.with_suffix(".puml")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/flowchart_render.py (reported line 216)May include surrounding context.

python
# 生成 SVG
        svg_cmd = list(plantuml_cmd) + ["-tsvg", "-o", str(td), str(src)]
        try:
            subprocess.run(svg_cmd, check=True, capture_output=True, text=True)
        except subprocess.CalledProcessError as e:
            raise RuntimeError(
                f"plantuml 生成 SVG 失败:\nSTDOUT: {e.stdout}\nSTDERR: {e.stderr}"

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/flowchart_render.py (reported line 228)May include surrounding context.

python
# 用 -z(zoom)放大让矢量字渲染更精细
        zoom_args = ["-z", str(scale)] if scale and abs(scale - 1.0) > 0.01 else []
        try:
            subprocess.run(
                ["rsvg-convert", "-f", "pdf"] + zoom_args + ["-o", str(out), str(svg_path)],
                check=True, capture_output=True, text=True,
            )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
85% confidence
Finding

This Python file contains natural-language documentation and user-visible text exclusively in Chinese, including the module docstring and the error raised in get_style. For a general-purpose skill, forcing one language without offering a choice can violate language/locale policy requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

This YAML file uses Chinese text for the title and all user-visible labels, but provides no indication that the locale is configurable or that Chinese is a justified, region-specific requirement. Under the policy rule, forcing a specific language without user opt-in is a natural-language locale violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

This manifest uses Chinese natural-language labels throughout the title and node text, which imposes a specific language on users without any opt-in, alternative locale, or justification that the skill is region-specific. Under the policy rule, fixed language/locale content can be a natural-language policy violation when no user choice or documented scope is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This manifest uses Chinese labels and titles throughout, which can impose a specific language on users without any visible opt-in or justification. The policy requires either offering a language/locale choice or clearly documenting why the locale constraint is intentional.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The title and all user-visible labels are written entirely in Chinese, which indicates a fixed language choice. The file does not offer a language/locale option or explain that the skill is intentionally region-specific, so it may violate the policy against forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The exception text shown to users when PyYAML is missing is only in Chinese. This enforces a specific language for an interactive/user-visible message without offering a language choice or documenting a justified locale limitation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.