Back to skill

Security audit

code-to-diagram

Security checks for vulnerabilities and agentic risk

Overview

This diagram skill is mostly purpose-aligned, but its renderer can automatically run an unpinned npm command and has file-deletion and browser-sandbox risks users should review before installing.

Install only if you are comfortable with a diagram tool that runs local renderers over repository-derived content. Prefer preinstalling a trusted, pinned Mermaid CLI and avoiding the npx fallback; run it in a constrained workspace without secrets; and avoid passing important existing .mmd files because the script may delete them after rendering.

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

Error
Location
scripts/code_to_diagram.js:503
Finding
Automatic Execution of an Unpinned npm Package Through npx<![CDATA[ ## Vulnerability Details **File Location**: `scripts/code_to_diagram.js:503-546` **Vulnerability Type**: Unpinned dependency retrieval and execution **Risk Level**: High ### Vulnerable Code ```js function renderWithMmdc(inputMmdPath, pngPath, args) { let mmdc = resolveMmdc() let useNpx = false if (!mmdc) { console.log('⚙️ 未直接找到 mmdc,将通过 npx 调用 @mermaid-js/mermaid-cli …') useNpx = true } else { console.log(`🔧 使用官方渲染器 mmdc:${mmdc}`) } const theme = THEMES[args.theme] if (!theme) { console.error(`❌ 未知主题:${args.theme}`) console.error(` 可用主题:${AVAILABLE_THEMES.join(', ')}`) process.exit(1) } const mermaidConfig = buildMermaidConfig(theme, args) const configFile = path.join(os.tmpdir(), `code_to_diagram_mermaid_config_${Date.now()}.json`) fs.writeFileSync(configFile, JSON.stringify(mermaidConfig, null, 2)) const puppeteerCfg = writePuppeteerConfig() const chineseFontCss = writeChineseFontCss(args.font) const bgColor = args.transparent ? 'transparent' : (args.bg || theme.bg) const mmdcArgs = [ ...(useNpx ? ['mmdc'] : []), '-i', inputMmdPath, '-o', pngPath, '-c', configFile, '-b', bgColor, '-w', String(args.width), '-H', String(args.height), '-s', String(args.scale), '-p', puppeteerCfg, '-C', chineseFontCss, ] const cmd = useNpx ? 'npx' : mmdc const result = spawnSync(cmd, mmdcArgs, { stdio: 'inherit', shell: false }) ``` ### Technical Analysis When a local or global `mmdc` executable cannot be found, the renderer automatically invokes: ```bash npx mmdc ... ``` This command does not use `--no-install`, an exact version, a verified integrity value, or the explicitly documented package name `@mermaid-js/mermaid-cli`. Depending on the npm/npx version and local cache state, `npx` may retrieve and execute the package currently resolved under the unscoped name `mmdc`. The status message claims that the official scoped Mermaid CLI package will be us ...[truncated 1895 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic package downloading from the normal rendering path. 2. Require a preinstalled and explicitly trusted Mermaid CLI executable. 3. If a local npm dependency is supported, declare an exact version of `@mermaid-js/mermaid-cli` in `package.json`, preserve its integrity in `package-lock.json`, and execute only `node_modules/.bin/mmdc`. 4. Use `npx --no-install mmdc` if npx is retained solely as a launcher for an already installed dependency. 5. If runtime downloading is unavoidable: - Require explicit user confirmation. - Use the exact scoped package and a pinned version. - Validate the registry and package integrity. - Disable lifecycle scripts where operationally possible. - Run installation and rendering in an isolated, unprivileged container. 6. Make logs accurately identify the command and package that will actually be executed. 7. Fail closed when the trusted renderer is unavailable rather than silently changing to a network-capable execution path. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/code_to_diagram.js:324
Finding
Chromium Sandbox Disabled During Mermaid Rendering<![CDATA[ ## Vulnerability Details **File Location**: `scripts/code_to_diagram.js:324-330` **Vulnerability Type**: Unsafe browser security configuration **Risk Level**: Medium ### Vulnerable Code ```js function writePuppeteerConfig() { const cfg = { args: ['--no-sandbox', '--disable-setuid-sandbox'] } const ts = Date.now() const file = path.join(os.tmpdir(), `code_to_diagram_puppeteer_${ts}.json`) fs.writeFileSync(file, JSON.stringify(cfg)) return file } ``` The generated configuration is subsequently passed to Mermaid CLI through its Puppeteer configuration option: ```js const mmdcArgs = [ '-i', inputMmdPath, '-o', pngPath, '-c', configFile, '-p', puppeteerCfg, '-C', chineseFontCss, ] ``` ### Technical Analysis The Skill always starts the Chromium instance used by Mermaid CLI with both `--no-sandbox` and `--disable-setuid-sandbox`. These flags disable Chromium's principal process-containment mechanisms. Mermaid source may be generated from or influenced by an untrusted repository. Rendering therefore crosses a trust boundary: project-derived content is interpreted by Mermaid and Chromium. If that content reaches a renderer or browser vulnerability, disabling the sandbox removes an important containment layer that would otherwise limit access to the host. This configuration does not independently prove that arbitrary Mermaid input can execute operating-system commands. Exploitation requires a vulnerability in Mermaid, Puppeteer, Chromium, or related rendering code. Nevertheless, forcing sandbox removal materially increases the impact of such a vulnerability. ### Attack Path 1. An attacker places specially crafted source or diagram-related content in a repository analyzed by the Skill. 2. The content influences the Mermaid document passed to the renderer. 3. The Skill generates a Puppeteer configuration that disables all supported Chromium sandbox mechanisms. 4. Mermaid CLI starts Chromium using that configuration and processes the ...[truncated 910 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox` from the default Puppeteer configuration. 2. Run Mermaid CLI with Chromium's normal sandbox enabled whenever the host supports it. 3. If the host cannot provide browser sandboxing, execute rendering inside a dedicated container or sandbox with: - A non-root user. - A read-only root filesystem. - A narrowly scoped writable output directory. - No access to credential directories or unrelated repositories. - Restricted or disabled outbound network access. - CPU, memory, process, and execution-time limits. 4. Expose any no-sandbox compatibility mode as an explicit opt-in option with a clear security warning. 5. Keep Mermaid CLI, Puppeteer, and Chromium patched and version-pinned. 6. Treat Mermaid and SVG documents derived from external repositories as untrusted input. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
声明描述的是一个完整的图表/架构图生成与渲染能力,而实际代码仅是一个低层图形工具模块:根据点集计算不同插值方式的 SVG 路径数据。它既不分析源码,也不构建 Mermaid 或架构图,更没有 PNG 渲染流程。虽然生成 SVG path 可能可作为绘图系统的底层组成部分,但就该代码片段本身而言,其主要用途与声明的核心功能明显不一致,因此应判定为描述与行为不匹配。

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
声明的核心功能是从源代码生成图表并渲染图片,而代码片段的实际核心功能是对现有 SVG 文件进行静态校验和一次可选的渲染可用性测试。虽然脚本里有用 rsvg-convert 生成临时 PNG 的步骤,但这只是验证 SVG 能否被渲染,不是按照描述进行 Mermaid/SVG 图生成或正式图片渲染流水线。两者主目的明显不同:描述是“生成图”,代码是“验图”。因此属于明显的描述与行为不符。

Hidden Instructions

High
Category
Prompt Injection
Content
stroke="{stroke}" stroke-width="1.5"/>
<line x1="{cx+w/2}" y1="{top}" x2="{cx+w/2}" y2="{top+h}"
      stroke="{stroke}" stroke-width="1.5"/>
<!-- 内环(向量数据库专用) -->
<ellipse cx="{cx}" cy="{top+h*0.33}" rx="{w/2}" ry="{w/6}"
         fill="none" stroke="{stroke}" stroke-width="0.7" opacity="0.5"/>
<ellipse cx="{cx}" cy="{top+h*0.66}" rx="{w/2}" ry="{w/6}"
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
stroke="{stroke}" stroke-width="1.5"/>
<line x1="{cx+w/2}" y1="{top}" x2="{cx+w/2}" y2="{top+h}"
      stroke="{stroke}" stroke-width="1.5"/>
<!-- 内环(向量数据库专用) -->
<ellipse cx="{cx}" cy="{top+h*0.33}" rx="{w/2}" ry="{w/6}"
         fill="none" stroke="{stroke}" stroke-width="0.7" opacity="0.5"/>
<ellipse cx="{cx}" cy="{top+h*0.66}" rx="{w/2}" ry="{w/6}"
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Hidden Instructions

High
Category
Prompt Injection
Content
SVG 无法实现真正的 backdrop-filter,通过三层叠加模拟:

```xml
<!-- 层 1: 微弱内阴影 -->
<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="12"
      fill="rgba(255,255,255,0.03)" stroke="none"/>
<!-- 层 2: 毛玻璃主体 -->
Confidence
70% confidence
Finding
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The README states that the final generated content includes '代码逻辑解释(中文)', which imposes a specific language requirement in the skill description. This is a natural-language policy concern because it does not offer the user a language choice or describe the Chinese-only behavior as optional or region-specific.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The markdown explicitly states that node labels and edge descriptions "must use Chinese," which forces a specific language regardless of user preference. This is a natural-language policy issue because the file does not provide an opt-in, alternative language option, or a documented region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
This markdown file is written entirely in Chinese and does not indicate that users may choose another language or that the Chinese-only format is required for a region-specific purpose. Under the natural-language policy criteria, forcing a specific language without user opt-in is a locale-policy concern.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
Line L169 states that text labels must use Chinese, which is a language/locale requirement expressed in natural language. The file does not provide an opt-in, alternative language option, or a documented region-specific justification, so this conflicts with the policy on forcing a specific language.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
This markdown file includes a natural-language rule requiring that all text labels use Chinese. That is a language-policy constraint applied unconditionally, and the file does not provide user opt-in, alternatives, or a region-specific justification.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
This markdown file contains a natural-language rule stating that text labels must use Chinese. That is a language-policy constraint without user opt-in, and the file does not provide a region-specific justification or an alternative language choice.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
Line L156 states that text labels must use Chinese, which is a natural-language locale requirement. The file does not provide user opt-in, alternatives, or a documented region-specific justification, so this conflicts with the language/locale policy requirement.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
Line L205 states that text labels must use Chinese, which is a natural-language locale requirement. The file does not provide an opt-in choice or explain a region-specific justification, so this is a language/locale policy violation under the stated rules.

Vague Triggers

Medium
Confidence
89% confidence
Finding
This markdown file includes activation-like matching logic based on generic words such as "文档", "博客", "现代", and "高端". These terms are broad descriptors used in everyday requests, and the file provides no exclusion conditions or negative examples to clarify when they should or should not trigger a style choice.

Description-Behavior Mismatch

Medium
Confidence
84% confidence
Finding
The help text and manifest describe a skill that generates Mermaid flowcharts or SVG architecture diagrams, implying both input types are supported as part of the main rendering workflow. In code, cmdRender always reads --file as Mermaid input and passes it to mmdc, while SVG support exists only behind a separate --engine svg path, so the advertised file-based behavior is broader than the default implementation actually provides.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script deletes user-supplied `.mmd` files after rendering when `args.file` is set and the input path ends with `.mmd`, even if that file was not a temporary intermediate file. In a skill context that processes user-provided paths, this can destroy user data unexpectedly and can be abused to cause denial of service or destructive file loss if an attacker can influence the file path passed to the script.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The comment for `stepBeforeCurve` says "先垂直后水平" (vertical first, then horizontal), but the code computes a midpoint Y and draws to `(same x, midY)` then `(next x, midY)`, which is effectively horizontal-at-midlevel behavior rather than stepping first to the next point's Y. Likewise, `stepAfterCurve` is documented as "先水平后垂直" but uses a midpoint X and draws to `(midX, same y)` then `(midX, next y)`, which does not match the named/documented step-after semantics.

Natural-Language Policy Violations

Low
Confidence
76% confidence
Finding
The natural-language instructions and decision tree are written primarily in Chinese and frame matching around Chinese user utterances, with only limited English keywords included. There is no statement that the skill is China/Chinese-specific, nor any opt-in or alternative language behavior for users in other locales.

Natural-Language Policy Violations

Low
Confidence
96% confidence
Finding
The script's user-facing help, warnings, and status messages are presented in Chinese, with no option to select another language or locale. This creates a language/locale policy issue because the skill effectively forces one language for interaction rather than offering user choice or documenting a justified region-specific constraint.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
The documentation frames the script as using the official Mermaid renderer to produce output consistent with Markdown preview. However, when --no-png is set, the code bypasses mmdc entirely and only writes a Markdown code block, so that documented rendering behavior does not apply to all advertised execution paths.

Intent-Code Divergence

Low
Confidence
98% confidence
Finding
The inline documentation explicitly states '此脚本仅生成 PNG 图片', which contradicts the actual behavior. The implementation writes .md files in both cmdRender and cmdRenderSvg, and --no-png skips image generation entirely while still producing Markdown output.

Natural-Language Policy Violations

Low
Confidence
92% confidence
Finding
This TypeScript file's natural-language comments and API descriptions are entirely in Chinese, with no indication that the skill is region-specific or that alternative language support is available. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The file's natural-language comments and function descriptions are written exclusively in Chinese, which imposes a specific language context without any visible user opt-in or justification for a locale-specific skill. The policy explicitly flags language or locale constraints when the skill does not offer a choice or document a justified regional scope.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/code_to_diagram.js:309