Back to skill

Security audit

Mindmap Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill does what it says by making mindmaps for Telegram, but it sends potentially private assistant context to Telegram and runs an unpinned renderer with weak isolation.

Review before installing. Use this only for content you are comfortable sending to a configured Telegram chat, verify the chat ID and bot token handling, and avoid sensitive meeting, calendar, memory, or business data unless the environment is trusted. Prefer a pinned local Mermaid CLI install, disable runtime npx fetching, and run rendering in an isolated low-privilege environment.

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 (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/render_mindmap.sh:65
Finding
Automatic Retrieval and Execution of an Unpinned npm Package<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render_mindmap.sh`, lines 65–76 **Vulnerability Type**: Mutable remote dependency retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash # Render using mermaid-cli (mmdc) # Priority: global install > local node_modules > npx auto-install if command -v mmdc &> /dev/null; then MMDC_CMD="mmdc" elif [[ -x "./node_modules/.bin/mmdc" ]]; then MMDC_CMD="./node_modules/.bin/mmdc" elif [[ -d "/tmp/mmdc-test/node_modules" ]]; then # Use the local install we set up for testing MMDC_CMD="/tmp/mmdc-test/node_modules/.bin/mmdc" else # Auto-install via npx as last resort MMDC_CMD="npx -y @mermaid-js/mermaid-cli" fi ``` ### Technical Analysis When no existing Mermaid CLI installation is found, the script invokes `npx -y @mermaid-js/mermaid-cli`. This command automatically downloads and executes the package resolved by the npm registry without: - Pinning an exact version - Using a reviewed lockfile - Verifying an integrity hash - Requesting user confirmation - Restricting package lifecycle or runtime behavior Consequently, the effective executable payload can change after the Skill has been reviewed. A compromised package release, maintainer account, registry response, or transitive dependency could introduce arbitrary code that would execute with the permissions and environment of the Agent process. ### Attack Path 1. An attacker compromises the npm package, its maintainer account, or a transitive dependency. 2. The target environment does not have `mmdc` in `PATH` and lacks the expected local installation. 3. A user or Agent triggers mindmap rendering. 4. The renderer selects `npx -y @mermaid-js/mermaid-cli`. 5. `npx` retrieves the current mutable package and its dependency graph from the npm registry. 6. Package installation or runtime code executes under the Agent account. 7. Malicious code can access resources available to that account, including environment vari ...[truncated 685 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic package installation from the runtime path. 2. Pin an exact reviewed version of `@mermaid-js/mermaid-cli` in `package.json`; do not use a floating version or range. 3. Commit and enforce a package lockfile containing integrity metadata. 4. Install dependencies during a controlled build or deployment phase rather than during Skill execution. 5. Invoke only the reviewed local executable, for example: ```bash MMDC_CMD=(./node_modules/.bin/mmdc) if [[ ! -x "${MMDC_CMD[0]}" ]]; then echo "Error: Pinned mermaid-cli dependency is not installed" >&2 exit 1 fi ``` 6. If `npx` must be retained, use `npx --no-install` so it cannot retrieve missing packages. 7. Verify package provenance and integrity in CI, and use dependency scanning and update review procedures. 8. Run the renderer in a restricted environment without credentials and with outbound network access disabled. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/render_mindmap.sh:35
Finding
Untrusted Mermaid Content Is Rendered with the Chromium Sandbox Disabled<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render_mindmap.sh`, lines 35–45 **Vulnerability Type**: Unsafe browser sandbox configuration **Risk Level**: High ### Vulnerable Code ```bash PUPPETEER_CONFIG=$(mktemp /tmp/mmdc-puppeteer-XXXXXX.json) cat > "$PUPPETEER_CONFIG" <<'EOF' { "headless": true, "args": [ "--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage" ] } EOF ``` ### Technical Analysis The renderer processes Mermaid input derived from user conversations, meeting notes, goals, and other potentially untrusted content. Mermaid CLI uses Puppeteer and Chromium to render that content. The configuration explicitly supplies both `--no-sandbox` and `--disable-setuid-sandbox`. These options disable Chromium's principal process-isolation mechanisms. If crafted Mermaid content reaches a vulnerability in Mermaid, Chromium, Puppeteer, font parsing, SVG handling, or another browser component, exploitation would not be contained by the Chromium sandbox. This configuration does not independently establish a browser exploit. It materially increases the impact of any applicable renderer or browser vulnerability by removing a major defense-in-depth boundary. ### Attack Path 1. An attacker provides specially crafted text that is incorporated into a generated Mermaid document. 2. The Agent passes the document to `render_mindmap.sh`. 3. Mermaid CLI launches Chromium using the generated Puppeteer configuration. 4. Chromium processes the attacker-influenced document with its sandbox disabled. 5. If the content triggers a vulnerability in the rendering stack, exploit code executes directly with the privileges of the renderer process rather than being constrained by Chromium's sandbox. 6. The exploit can then attempt to access Agent-readable files, environment variables, or network services. ### Impact Assessment The impact depends on the presence of an exploitable vulnerability in the rendering stac ...[truncated 502 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--no-sandbox` and `--disable-setuid-sandbox`. 2. Configure the host so Chromium's supported sandbox can operate correctly. 3. Run rendering as a dedicated, unprivileged operating-system user. 4. Place rendering inside a hardened container or equivalent isolation boundary with: - A read-only root filesystem - No mounted credentials - No access to the host filesystem except a private input/output directory - Outbound network access disabled - Dropped Linux capabilities - `no-new-privileges` - CPU, memory, process, and execution-time limits 5. Keep Mermaid CLI, Chromium, Puppeteer, and their dependencies pinned and patched. 6. Validate Mermaid input and reject unsupported directives or excessively complex content before rendering. 7. Ensure the renderer environment does not inherit `TELEGRAM_BOT_TOKEN` or unrelated secrets. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_and_send.sh:30
Finding
Predictable Shared Temporary Files Allow Symlink Attacks and Sensitive-Data Retention<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_and_send.sh`, lines 30–76 **Vulnerability Type**: Unsafe temporary-file creation and incomplete cleanup **Risk Level**: Medium ### Vulnerable Code ```bash # Generate unique temp filenames TIMESTAMP=$(date +%Y%m%d_%H%M%S) INPUT_FILE="/tmp/mindmap_${TIMESTAMP}.mmd" OUTPUT_FILE="/tmp/mindmap_${TIMESTAMP}.png" # Read mermaid content from STDIN if [[ -t 0 ]]; then echo "Error: No input provided. Pipe Mermaid mindmap syntax via STDIN." >&2 echo "Example: echo 'mindmap\n root((Topic))' | $0 $CHAT_ID" >&2 exit 1 fi cat > "$INPUT_FILE" ``` The affected cleanup and error-handling path is: ```bash "$SCRIPT_DIR/render_mindmap.sh" "$INPUT_FILE" "$OUTPUT_FILE" if [[ $? -ne 0 || ! -f "$OUTPUT_FILE" ]]; then echo "Error: Rendering failed. Sending text fallback to Telegram..." >&2 # Fallback: send the raw content as a text message TEXT_CONTENT=$(cat "$INPUT_FILE") curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ -F "chat_id=$CHAT_ID" \ -F "text=⚠️ Couldn't render the mindmap as an image. Here's the structure:\n\n$TEXT_CONTENT" \ -F "parse_mode=HTML" \ > /dev/null 2>&1 rm -f "$INPUT_FILE" exit 1 fi # Step 2: Send to Telegram echo "📱 Step 3/3: Sending to Telegram..." "$SCRIPT_DIR/send_telegram_photo.sh" "$OUTPUT_FILE" "$CAPTION" "$CHAT_ID" # Cleanup temp files rm -f "$INPUT_FILE" "$OUTPUT_FILE" ``` ### Technical Analysis The script generates names using a timestamp with one-second precision and places them directly in the shared `/tmp` directory. It does not use `mktemp`, exclusive creation, a private temporary directory, or a restrictive `umask`. A local attacker can predict a filename and create it in advance as a symbolic link. The redirection in `cat > "$INPUT_FILE"` follows symbolic links, allowing the script to overwrite another file writable by the Agent account. Concurrent runs within th ...[truncated 2514 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Set restrictive permissions before creating any temporary content: ```bash umask 077 ``` 2. Create a private temporary directory using `mktemp -d`: ```bash TEMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/mindmap.XXXXXX") INPUT_FILE="$TEMP_DIR/input.mmd" OUTPUT_FILE="$TEMP_DIR/output.png" ``` 3. Register cleanup immediately so it executes on success, failure, or interruption: ```bash cleanup() { rm -rf -- "$TEMP_DIR" } trap cleanup EXIT HUP INT TERM ``` 4. Handle failures inside conditional commands so `set -e` does not bypass fallback behavior: ```bash if ! "$SCRIPT_DIR/render_mindmap.sh" "$INPUT_FILE" "$OUTPUT_FILE"; then echo "Error: Rendering failed" >&2 # Perform the intended fallback here. exit 1 fi if ! "$SCRIPT_DIR/send_telegram_photo.sh" \ "$OUTPUT_FILE" "$CAPTION" "$CHAT_ID"; then echo "Error: Telegram delivery failed" >&2 exit 1 fi ``` 5. Do not use timestamp-only names in shared directories. 6. Confirm temporary files are regular files and are not symbolic links before use. 7. Apply execution locking or per-run private directories to prevent concurrent collisions. 8. Avoid retaining raw conversation-derived content longer than required for rendering and delivery. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill description presents a simple visualization feature, but the instructions also require direct message delivery to Telegram using shell scripts and implicit credentials such as CHAT_ID and likely bot tokens. This mismatch can hide sensitive outbound behavior from users and reviewers, making data exfiltration or unauthorized messaging more likely because the operational behavior is broader than the declared purpose.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README explicitly states that generated mindmaps are delivered via Telegram Bot API, which implies user conversation content, goals, decisions, or meeting notes may be sent to a third-party platform. Failing to disclose this data transfer can cause unintentional exposure of potentially sensitive information and prevents operators from making an informed trust and privacy decision before deployment.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill invokes shell commands and external scripts to render files and send Telegram messages, but it declares no explicit tool scope or permissions boundary. That creates an authorization gap where a host agent may execute shell-capable actions without clear review, increasing the chance of unintended command execution, data handling, or exfiltration through side effects.

Natural-Language Policy Violations

Medium
Confidence
91% confidence
Finding
The skill mandates Telegram as the only output channel and says to always send the PNG inline, without requiring user confirmation or offering a safe local-only default first. In context, the content being visualized may include meeting notes, goals, decisions, or memory context, so forcing external transmission can leak sensitive personal or business information to a third-party messaging channel.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The guidance explicitly tells the skill to use calendar, memory, and messages as fallback inputs when direct notes are unavailable, but it provides no requirement to verify user intent, minimize data use, or warn that private contextual data may be pulled in. In a personal-assistant skill operating over sensitive conversations and histories, this can cause unauthorized or surprising inclusion of private information in generated mindmaps or Telegram-delivered images.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
On render failure, the script automatically transmits the raw Mermaid input to Telegram as a text message without any explicit consent or warning at the point of transmission. Since the input may contain meeting notes, goals, decisions, or other sensitive conversation-derived content, this fallback can leak more data than the user expected when asking for an image render.

External Transmission

Medium
Category
Data Exfiltration
Content
# Fallback: send the raw content as a text message
    TEXT_CONTENT=$(cat "$INPUT_FILE")
    curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
        -F "chat_id=$CHAT_ID" \
        -F "text=⚠️ Couldn't render the mindmap as an image. Here's the structure:\n\n$TEXT_CONTENT" \
        -F "parse_mode=HTML" \
Confidence
88% confidence
Finding
This code sends content to the Telegram Bot API, which is an expected external service for this skill, but here it transmits the full raw input content during an error path. In the context of a mindmap generator built from conversations and priorities, that content can contain sensitive user data, so the external transmission becomes security-relevant when it exceeds the user's likely expectation of sending only a rendered image.

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.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
For a rendering utility, automatically downloading and executing Mermaid CLI via `npx` is unnecessary and materially increases attack surface. In the context of a mindmap-generation skill that processes user-controlled content, this is more dangerous because rendering already invokes a headless browser with `--no-sandbox`, so any malicious or compromised downloaded tool would execute in a relatively weakly isolated environment.

Rp1

Medium
Category
MCP Rug Pull
Confidence
98% confidence
Finding
The script falls back to `npx -y @mermaid-js/mermaid-cli`, which can fetch and execute code from the network at runtime without a pinned version. That creates a supply-chain risk: a compromised package, dependency, registry response, or unexpected version update could result in arbitrary code execution in the environment running this skill.

External Transmission

Medium
Category
Data Exfiltration
Content
echo "Warning: Caption truncated to 1024 characters" >&2
fi

TELEGRAM_API="https://api.telegram.org/bot${BOT_TOKEN}/sendPhoto"

echo "Sending mindmap to Telegram chat $CHAT_ID..."
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.