Back to skill

Security audit

Markdown Diagram Renderer

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it claims, but it can automatically send diagram content to third-party renderers, including PlantUML over plaintext HTTP, and can overwrite Markdown files in place.

Install only if you are comfortable with Markdown diagram contents being sent to external rendering services when local tools are unavailable. Avoid using it on confidential architecture, credentials, network topology, or private business documents unless local renderers are installed and network fallback is disabled or removed. Use backups or an explicit output workflow because the default behavior can overwrite the input Markdown file.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
script/core.py:328
Finding

PlantUML Diagram Source Is Transmitted over Plaintext HTTP

Content
View full analysis
str: """PlantUML 特殊编码""" compressed = zlib.compress(text.encode('utf-8'))[2:-4] encoded = base64.b64encode(compressed).decode('ascii') return encoded.replace('+', '-').replace('/', '_') encoded = encode_plantuml(code.strip()) url = f"http://www.plantuml.com/plantuml/{output_format}/{encoded}" request = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) with urllib.request.urlopen(request, timeout=15) as response: img_data = response.read() ``` ### Technical Analysis When local PlantUML rendering is unavailable or fails, the implementation automatically falls back to the public PlantUML service. The complete diagram source is compressed, Base64-encoded, placed in the URL path, and transmitted using unencrypted HTTP. Compression and Base64 encoding do not provide confidentiality. Any network intermediary capable of observing HTTP traffic can recover the diagram source. Because the encoded source is placed in the URL, it may also be recorded by HTTP proxies, gateways, monitoring products, browser-equivalent infrastructure, or server access logs. Online rendering is consistent with the Skill's declared functionality and is disclosed in `SKILL.md`. However, plaintext transport is not necessary to provide that functionality and exceeds the minimum safe network behavior. The implementation should not expose potentially sensitive architecture information when encrypted transport is available. ### Attack Path 1. A user processes a Markdown document containing a PlantUML diagram. 2. The diagram contains sensitive information such as internal hostnames, network topology, database names, credentials, access tokens, or proprietary system relationships. 3. Local rendering fail ...[truncated 1241 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
script/core.py:198
Finding

Sensitive Diagram Source May Persist in Temporary Files after Rendering Failures

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The skill description understates important behaviors: it can send diagram content to third-party services, heuristically process code blocks without explicit tags, and rewrite documents by embedding rendered output. In context, this is dangerous because Markdown files may contain sensitive internal architecture or secrets in code blocks, and users may invoke the skill expecting only local rendering and explicit diagram handling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The PlantUML fallback transmits diagram contents to a remote server over plain HTTP rather than HTTPS. This leaks sensitive content to the remote service and also exposes it to interception or modification in transit, making the risk materially worse than a typical undisclosed network fallback.

Content

No source excerpt is available for this finding.

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 · README.md (reported line 41)May include surrounding context.

md
brew install graphviz

# Ubuntu/Debian
sudo apt-get install graphviz

# Windows
# Download installer: https://graphviz.org/download/

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 · SKILL.md (reported line 44)May include surrounding context.

md
brew install graphviz

# Ubuntu/Debian
sudo apt-get install graphviz

# Windows
# Download installer: https://graphviz.org/download/

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README states that the tool will automatically fall back to online rendering services when local tools are unavailable, but it does not clearly warn that diagram contents from user documents may be transmitted to third-party services. In a markdown-processing skill, those diagrams may contain internal architecture, credentials, network topology, or other sensitive material, so silent network exfiltration is a real privacy and security risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill declares no explicit tool/permission scope even though its documented behavior involves filesystem reads/writes, environment access, shell execution, and optional network access. In an agent setting, missing scope declarations can cause the skill to run with broader privileges than users or orchestrators expect, increasing the risk of unintended file modification and data exfiltration through online rendering backends.

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 · script/core.py (reported line 205)May include surrounding context.

python
with tempfile.NamedTemporaryFile(suffix=f'.{output_format}', delete=False) as dst:
                dst_path = dst.name
            
            result = subprocess.run(
                ['mmdc', '-i', src_path, '-o', dst_path, '-b', 'white'],
                capture_output=True,
                timeout=30

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest only states that the skill identifies diagram code blocks in Markdown, renders them, and replaces them; it does not indicate that it will spawn local CLI tools such as mmdc or run Java with a PlantUML JAR. Process execution is a materially stronger capability than ordinary Markdown processing and is not evident from the declared purpose alone.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The Mermaid fallback sends user-supplied diagram contents to mermaid.ink, which is an external service not disclosed in the skill description. This creates a confidentiality and data-governance risk because Markdown content may contain sensitive architecture, internal names, or secrets embedded in diagrams.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The Mermaid online fallback silently exfiltrates diagram content to a third party without an explicit user-facing warning. In a Markdown-processing skill, users are likely to expect local transformation, so undisclosed network transmission is particularly risky.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The code launches Java with a PlantUML jar path partly controlled by the PLANTUML_JAR environment variable. Although shell injection is not present, environment-controlled executable content can cause execution of an attacker-supplied jar, resulting in arbitrary code execution in the skill's runtime context.

Content

Scanner excerpt · script/core.py (reported line 293)May include surrounding context.

python
src.write(code.strip())
                src_path = src.name
            
            result = subprocess.run(
                ['java', '-jar', plantuml_jar, f'-t{output_format}', src_path],
                capture_output=True,
                timeout=30

Tainted flow: 'plantuml_jar' from os.environ.get (line 287, credential/environment) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
97% confidence
Finding

PLANTUML_JAR is sourced from the environment and then executed by Java via subprocess. If an attacker can influence the environment, they can point this value to a malicious jar and gain arbitrary code execution under the privileges of the running process.

Content

Scanner excerpt · script/core.py (reported line 293)May include surrounding context.

python
src.write(code.strip())
                src_path = src.name
            
            result = subprocess.run(
                ['java', '-jar', plantuml_jar, f'-t{output_format}', src_path],
                capture_output=True,
                timeout=30

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The PlantUML online fallback sends content to a remote server without warning and does so via HTTP, compounding privacy risk with transport insecurity. An attacker on the network path could observe or tamper with the request or response.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The function overwrites the original Markdown file in place after replacing content, without any safeguard, prompt, backup, or alternate output path. This can lead to unintended data loss or irreversible modification of user files, especially when rendering untrusted or misdetected code blocks.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill defaults to modifying the input Markdown file in place when no output path is provided, which can silently overwrite original user content. In this skill’s context, rendering untrusted diagram blocks and then writing replacements back to the same file increases the risk of accidental data loss or destructive changes without clear user acknowledgment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The opening description says the skill will 'replace' diagrams in Markdown documents, which implies file modification, but the destructive default is not disclosed until much later in the Notes section. For a markdown skill description, modification of user files should be made prominent up front so users understand the impact before use.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The module’s visible natural-language documentation and user-facing error/log strings are written in Chinese throughout, which suggests a fixed language experience. There is no indication in this file that users can choose another language or that the locale restriction is intentional and documented as region-specific.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

Reading environment configuration for selecting the PlantUML jar expands the trust boundary beyond the file being processed. In this skill, that environment-derived value later controls what code Java executes, so even the configuration read itself is security-relevant.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language descriptions, docstrings, logs, and CLI help are written only in Chinese, which imposes a specific language on users without offering a language choice. This can violate organizational language or locale policies when skills are expected to be language-neutral or user-selectable.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The file’s natural-language comments are entirely in Chinese, including the skill description and dependency notes. This can reflect a language-specific constraint without any indication of user choice or opt-in, which matches the policy category for forced language or locale.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Using an unpinned dependency range for mistletoe allows future installs to pull newer versions that may introduce breaking changes or known vulnerabilities. In a skill that parses attacker-controlled Markdown, dependency drift increases supply-chain and parser-exposure risk because parsing libraries often process untrusted structured input.

Content

Scanner excerpt · script/requirements.txt (reported line 5)May include surrounding context.

text
# Python 依赖

# Markdown AST 解析
mistletoe>=0.9.0

# Graphviz 图表渲染
graphviz>=0.20.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using an unpinned dependency range for graphviz permits uncontrolled version selection at install time, which can introduce vulnerable or incompatible releases. In this skill's context, rendering diagrams may involve processing untrusted content and invoking external tooling, so supply-chain drift is more dangerous than in a purely local utility.

Content

Scanner excerpt · script/requirements.txt (reported line 8)May include surrounding context.

text
mistletoe>=0.9.0

# Graphviz 图表渲染
graphviz>=0.20.0

# 可选依赖(根据需要安装):
# - nodejs + @mermaid-js/mermaid-cli (用于 Mermaid 本地渲染)

Static analysis

No suspicious patterns detected.