Back to skill

Security audit

Generate Mindmap

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its mind-map purpose, but it can generate HTML that executes injected script content and can automatically install a Python package.

Install only if you trust the content being converted into maps, or avoid HTML/PNG/JPG rendering for untrusted outlines until the HTML escaping issue is fixed. Use --no-auto-install in shared or sensitive Python environments and install dependencies manually in an isolated environment. When opening generated HTML, understand that choosing the HTML save button in Chrome/Edge can enable autosave back to the selected file.

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)

T09 · Insecure Skill Coding Practices

Error
Location
generate_mindmap.py:1271
Finding
Untrusted Mind-Map Content Can Inject JavaScript into Generated HTML<![CDATA[ ## Vulnerability Details **File Location**: `generate_mindmap.py:1053`, `generate_mindmap.py:1215`, `generate_mindmap.py:1271-1275`, `generate_mindmap.py:3211-3218`, `generate_mindmap.py:3645-3646`, `generate_mindmap.py:3693-3694` **Vulnerability Type**: HTML and JavaScript injection through unsafe template substitution **Risk Level**: High ### Vulnerable Code The title is inserted directly into HTML text contexts: ```python <title>__TITLE__</title> ``` ```html <h1>&#x1F9E0; __TITLE__</h1> ``` Untrusted title and tree data are also inserted into an executable script element: ```html <script> /*__MINDMAP_DATA_START__*/ const RAW = __RAW_JSON__; const TITLE = __TITLE_JSON__; const INIT_THEME = "__THEME__"; /*__MINDMAP_DATA_END__*/ ``` The template substitutions do not perform HTML-parser-safe escaping: ```python def render_html(title, js_data, theme="midnight"): if theme not in THEMES: theme = "midnight" return (_HTML .replace("__TITLE__", title) .replace("__RAW_JSON__", js_data) .replace("__TITLE_JSON__", json.dumps(title, ensure_ascii=False)) .replace("__THEME__", theme) .replace("__DATE__", datetime.now().strftime("%Y-%m-%d %H:%M"))) ``` Both HTML generation and Playwright image rendering use this output: ```python if fmt in ("png", "jpg") and _has_playwright(): html_str = render_html(title, json.dumps(tree, ensure_ascii=False), theme=args.theme) _export_image_playwright(html_str, out, fmt, scale=args.scale, quality=args.quality) ``` ```python html = render_html(title, json.dumps(tree, ensure_ascii=False), theme=args.theme) open(out, "w", encoding="utf-8").write(html) ``` ### Technical Analysis The Skill accepts titles and node labels from command-line arguments, Markdown files, JSON files, or standard input. These values are therefore potentially untrusted. Al ...[truncated 3299 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not place raw JSON directly into an executable script context. 2. Store initial data in a non-executable element and safely parse it, for example: ```html <script id="mindmap-data" type="application/json">SAFE_JSON</script> ``` ```javascript const RAW = JSON.parse(document.getElementById("mindmap-data").textContent); ``` 3. Even in an `application/json` element, escape characters significant to the HTML parser. At minimum, encode: - `<` as `\u003c` - `>` as `\u003e` - `&` as `\u0026` - U+2028 as `\u2028` - U+2029 as `\u2029` 4. Apply context-specific HTML escaping to title substitutions used in `<title>` and `<h1>`, such as `html.escape(title, quote=True)`. 5. Avoid applying one placeholder replacement to both HTML and JavaScript contexts. Use separate, context-aware placeholders. 6. Add regression tests containing: - `</script>` - `<img src=x onerror=...>` - Quotes and backslashes - U+2028 and U+2029 - Nested malicious labels in both Markdown and JSON 7. Add a restrictive Content Security Policy. Refactor inline scripts and inline event handlers so that `script-src` does not require `unsafe-inline`. 8. Do not launch Chromium with `--no-sandbox` unless execution occurs inside a separately enforced operating-system sandbox or container. 9. If untrusted input must be rendered through Playwright, disable unnecessary browser capabilities and block outbound network requests during rendering. ]]>

T08 · Insecure Dependencies

Warning
Location
generate_mindmap.py:32
Finding
Runtime Installation of an Unpinned Third-Party Dependency<![CDATA[ ## Vulnerability Details **File Location**: `generate_mindmap.py:32-68` **Vulnerability Type**: Unpinned runtime package installation and environment mutation **Risk Level**: Medium ### Vulnerable Code ```python def _ensure_pillow(auto_install=True): """Import Pillow; optionally auto-install into the current environment. Safety: tries `pip install pillow`, then `pip install --user pillow`. Never uses --break-system-packages — on externally-managed Pythons (PEP 668) it prints instructions instead of forcing the install. Disable entirely with --no-auto-install. """ try: from PIL import Image # noqa: F401 return True except ImportError: pass if not auto_install: print("[mindmap] Pillow is required for this format. Install it with:", file=sys.stderr) print(" pip install pillow", file=sys.stderr) return False for extra in ([], ["--user"]): cmd = [sys.executable, "-m", "pip", "install", "pillow", "--quiet", "--disable-pip-version-check"] + extra print(f"[mindmap] Pillow not found — running: {' '.join(cmd)}", file=sys.stderr) try: subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) break except (subprocess.CalledProcessError, FileNotFoundError): continue ``` ### Technical Analysis When Pillow is unavailable and a PNG, JPG, or PDF export is requested, the Skill automatically invokes pip. The package is identified by its legitimate name, but no version constraint, lock file, package hash, index restriction, or integrity policy is applied. The installed artifact therefore depends on the invoking environment's current pip configuration, configured indexes, mirrors, and dependency-resolution state. Package installation may execute package-controlled build or installation logic with the same operating-system pr ...[truncated 1900 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic package installation from normal execution. 2. If Pillow is missing, terminate the affected export operation with explicit manual setup instructions. 3. Declare Pillow as an installation-time dependency in standard project metadata. 4. Pin Pillow to a reviewed and tested version or constrained version range. 5. For controlled deployments, use a lock file and verify package hashes. 6. Configure trusted package indexes explicitly in deployment documentation rather than inheriting arbitrary environment configuration. 7. If runtime installation is unavoidable: - Make it explicitly opt-in rather than enabled by default. - Ask for user confirmation before modifying the environment. - Display the selected index, package version, and full pip result. - Install into an isolated virtual environment dedicated to the Skill. - Avoid persistent `--user` installation. 8. Preserve installation logs instead of discarding both standard output and standard error. ]]>
Vulnerability Patterns
  • 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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Rogue AgentSelf-Modification, Session Persistence
Findings (28)

Vague Triggers

High
Confidence
96% confidence
Finding
The activation rule says the skill must be used whenever a user mentions mind maps, visualization, structuring notes, or exporting XMind/PNG/PDF, even if they did not explicitly ask for this skill. That broad trigger can hijack many ordinary summarization or organization requests and route them into a skill with file and shell capabilities, increasing unnecessary exposure to side effects and reducing user intent fidelity.

Ae1

High
Category
analysis-evasion
Content
`{baseDir}/examples/`:`ai_trends.html`、`product_launch.html`、`python_learning.html`(可直接用浏览器打开体验交互与主题切换),以及对应 `.json` 数据和 `outline_example.md` 大纲示例。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
`{baseDir}/examples/`:`ai_trends.html`、`product_launch.html`、`python_learning.html`(可直接用浏览器打开体验交互与主题切换),以及对应 `.json` 数据和 `outline_example.md` 大纲示例。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
`{baseDir}/examples/`:`ai_trends.html`、`product_launch.html`、`python_learning.html`(可直接用浏览器打开体验交互与主题切换),以及对应 `.json` 数据和 `outline_example.md` 大纲示例。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
�─────────────────────────────────
# CLI
# ─────────────────────────────────────────────────────────────────────────────
def parse_args():
    p = argparse.ArgumentParser(
        description="OpenClaw Mind Map Generator — cross-platform (macOS / Linux / Windows)"
    )
    p.add_argument("--title",   required=True,  help="Mind map title")
    p.add_argument("--output",  default=None,
                   help="Output file path (default: auto-detected workspace). "
                        "With multiple formats, the extension is swapped per format.")
    p.add_argument("--data",    default=None,
                   help="Inline mind-map data: JSON, or a Markdown outline "
                        "(auto-detected). Prefer --data-file for anything non-trivial.")
    p.add_a
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
p.add_argument("--quality", type=int,   default=92,
                   help="JPEG quality 1-100 (default: 92)")
    p.add_argument("--no-auto-install", action="store_true",
                   help="Never pip-install Pillow automatically; print instructions instead.")
    p.add_argument("--no-lint", action="store_true",
                   help="Skip the structure quality report.")
    return p.parse_args()
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises shell, file read/write, and environment-dependent behavior but does not declare any explicit tool scope or permissions boundary. This creates a least-privilege gap: an agent may invoke the skill with broader capabilities than necessary, increasing the chance of unintended file access, writes, or command execution in the host environment.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The skill uses the File System Access API to obtain a writable handle and can repeatedly overwrite the selected local HTML file with generated content. Although browser permission is required, the capability is still security-relevant because the app can persistently modify user files after initial consent, and the skill context encourages editing/export workflows where users may not expect continuous write access.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
After a file is bound, edits trigger automatic write-back without a strong, persistent warning at each save event. In an editor/export tool, that can lead to silent overwriting of local files, especially if users forget that auto-save is active or misunderstand the scope of the granted permission.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The HTML export control does more than a one-time export: on supporting browsers it initiates file binding and enables ongoing write-back to a user-selected file. That behavior materially changes the trust model from download/export to persistent modification, which can surprise users and cause unintended overwrites of local content.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This markdown file contains user-facing natural-language content exclusively in Chinese, and there is no indication that the user can opt into another language or that the skill is intentionally limited to a Chinese-speaking audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation.

Description-Behavior Mismatch

Medium
Confidence
93% confidence
Finding
The example HTML uses the File System Access API to bind a local HTML file and then silently write edits back to that same file. While the browser still requires an initial user-granted file handle, subsequent edits trigger automatic persistence without a fresh confirmation, which exceeds normal expectations for a simple viewer/export example and can cause unintended modification of local files.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
After a file is bound, edits are automatically written back to the local HTML file on a timer without an explicit per-save confirmation. In a skill context that encourages users to open generated HTML locally, this increases the chance of accidental overwrites, persistence of unwanted edits, or deceptive content silently being saved into trusted local documents.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The page binds a File System Access handle and then silently writes updated HTML back to that file after later edits via a debounced autosave path. Although initial binding requires user consent, subsequent writes happen automatically on many actions, which can unexpectedly overwrite local files and persist unintended or attacker-influenced content without an explicit per-save confirmation.

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This JSON skill content uses Chinese labels throughout, such as the central title and branch/topic names, with no indication that the user can choose another language or that the skill is intentionally limited to a Chinese-speaking audience. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
This skill auto-installs Pillow if it is missing, which is not necessary for safe operation of a content-generation tool and creates a supply-chain and environment-modification risk. A malicious or compromised package source, index configuration, or dependency path could cause arbitrary code execution during installation.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
Package installation is triggered automatically without an explicit confirmation or consent step from the user. In an agent or shared environment, that means a simple export request can unexpectedly alter the runtime and execute installer code, violating least surprise and least privilege.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"--quiet", "--disable-pip-version-check"] + extra
        print(f"[mindmap] Pillow not found — running: {' '.join(cmd)}", file=sys.stderr)
        try:
            subprocess.check_call(cmd, stdout=subprocess.DEVNULL,
                                  stderr=subprocess.DEVNULL)
            break
        except (subprocess.CalledProcessError, FileNotFoundError):
Confidence
94% confidence
Finding
The code invokes pip via subprocess to modify the current Python environment at runtime. Although it does not use shell=True and the command components are fixed, executing package installation from within a skill expands the skill's authority beyond mind-map generation and can introduce unreviewed code from package indexes into the host environment.

Session Persistence

Medium
Category
Rogue Agent
Content
def resolve_output(raw_path: str, fmt: str) -> str:
    """Expand ~, $HOME, %USERPROFILE%, create parent dirs, fix extension.

    If the path is just a filename without directory (e.g. 'mindmap.png'),
    it is placed under ~/.openclaw/workspace/ instead of the current dir.
Confidence
60% 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.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The HTML template sets `lang="zh-CN"`, and the interface strings throughout the embedded UI are Chinese-only, which effectively forces a specific language/locale. The file does not present a language choice or document this as a justified region-specific constraint.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file title and all operative instructions are written exclusively in Chinese, and line L003 instructs the model to read and follow this methodology before generating any mind map. There is no indication that users may choose another language or that the Chinese-only constraint is required for a region-specific purpose, which creates a language/locale policy concern.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The file declares a Chinese locale and presents the interface text entirely in Chinese, with no indication that users can choose another language. This can violate language/locale policy when a skill or interface forces a specific language without user opt-in.

Intent-Code Divergence

Low
Confidence
87% confidence
Finding
The inline edit documentation states '双击节点 / 选中后按 F2 或 Enter / 右键菜单「编辑文字」进入编辑', implying Enter starts text editing on a selected node. But the actual global keydown handler uses Enter to create a sibling node or child node instead, so the comment actively misstates the implemented behavior.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This JSON file contains all user-facing labels in Chinese, such as the central title and branch labels, with no indication that language selection is optional or that the file is intended only for a Chinese-speaking or region-specific context. Under the policy rule for natural-language violations, forcing a specific language without opt-in can be a locale-policy issue.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The root HTML element sets lang="zh-CN", and the interface text throughout the file is Chinese, which indicates a fixed language/locale experience. There is no visible opt-in, language selector, or justification that this skill is intentionally region-specific.

Static analysis

No suspicious patterns detected.