Back to skill

Security audit

Bug Data Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it needs review because its documentation conflicts with its bundled generator and it imports executable Python from an unbundled external skill path.

Install only if you are comfortable reviewing the generated training records and running a Python helper that depends on another local skill path. Prefer using the prompt-list script for reviewed instruction generation, and avoid running gen_bug_data.py in shared or sensitive environments unless the external data-generator path is trusted and output files are controlled.

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

Warning
Location
scripts/gen_bug_data.py:156
Finding

Unnecessary Execution of an Unbundled External Dependency

Content
View full analysis

Vulnerability Details

File Location: scripts/gen_bug_data.py, lines 156–159
Vulnerability Type: Unsafe import and execution of an external, unbundled Python module
Risk Level: Medium

Vulnerable Code

python
sys.path.insert(0, "/app/openclaw/skills/data-generator/scripts")
try:
    from build_prompt import build_prompt
    prompt = build_prompt(args.correct_tool, instructions)

Technical Analysis

The script prepends the absolute directory /app/openclaw/skills/data-generator/scripts to sys.path, imports build_prompt, and invokes it. The imported component is not included in this project and could not be audited with the rest of the Skill.

Python executes top-level module code during import. Therefore, importing build_prompt is itself a code-execution boundary, even before the imported function is called. Placing the external directory at index zero also gives it priority during module resolution.

The dependency is unnecessary in the current implementation: the returned prompt is only used to print its length, while the JSONL records are subsequently constructed directly. This also conflicts with the documentation's statement that the Skill does not depend on the internal implementation of data-generator.

Attack Path

  1. An attacker gains the ability to create or modify /app/openclaw/skills/data-generator/scripts/build_prompt.py, such as through a compromised Skill installation, writable shared directory, or supply-chain compromise.
  2. A user invokes scripts/gen_bug_data.py.
  3. The script places the external directory first in sys.path.
  4. Python loads the attacker-controlled build_prompt.py.
  5. Module-level payloads execute during import.
  6. The script then calls the attacker-controlled build_prompt() function.
  7. The payload operates with the same OS account, environment access, filesystem permissions, and process privileges as the generator.

Impact Assessment

Successful exploitation permits ar ...[truncated 435 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the external import and build_prompt() call because the resulting value is not needed to generate the output.
  2. Remove the sys.path.insert() modification.
  3. If this dependency is required in the future, package it as a normal, version-pinned dependency from a trusted source.
  4. Verify the dependency's integrity and provenance during installation.
  5. Ensure dependency directories are not writable by less-trusted users or processes.
  6. Avoid importing executable Python code from mutable shared Skill directories.
  7. Add automated tests confirming that JSONL generation succeeds without loading external Skill internals.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/gen_bug_data.py:254
Finding

Unvalidated Tool Name Injection into Generated Training Records

Content
View full analysis

Vulnerability Details

File Location: scripts/gen_bug_data.py, lines 254–255
Vulnerability Type: Improper construction of JSON-like tool-call content from unvalidated input
Risk Level: Low

Vulnerable Code

python
query_str = f"{action}{dev_name}"
tool_call = f'<tool_call>{{"tool_name":"{args.correct_tool}","query":"{query_str}"}}</tool_call>'

Technical Analysis

The user-controlled --correct-tool argument is embedded directly into a JSON-like string without validation or JSON serialization. A value containing quotation marks, braces, backslashes, or closing XML-style tags can terminate or alter the intended structure.

Although the complete output record is later serialized with json.dumps(), that outer serialization only protects the JSONL container. It does not validate or repair the inner JSON-like object stored inside the <tool_call> string.

As a result, crafted command-line input can generate malformed tool calls or inject additional structured text into assistant training messages. The issue affects generated data integrity rather than directly invoking a tool or OS command within this project.

Attack Path

  1. An attacker or untrusted automation supplies a crafted value through --correct-tool.
  2. The script interpolates the value directly into the tool_call string.
  3. The crafted value breaks out of the intended tool_name string or injects additional tags or fields.
  4. The manipulated string is written into an assistant conversation record in the output JSONL file.
  5. A downstream importer or model-training pipeline consumes the record without independently validating the embedded tool-call structure.
  6. The resulting dataset may contain malformed records or attacker-selected tool-call patterns.

Impact Assessment

The direct impact is limited to the integrity and reliability of generated training data. Possible consequences include rejected records, parser ambiguity, dataset corruption, or model pois ...[truncated 331 chars]

Remediation
View remediation

Remediation Suggestions

  1. Restrict tool names to an explicit allowlist of supported tools where possible.
  2. Otherwise, enforce a strict identifier pattern, such as ^[A-Za-z][A-Za-z0-9_.-]{0,63}$.
  3. Construct the complete tool-call object as a Python dictionary.
  4. Serialize the object exclusively with json.dumps() instead of manually interpolating JSON syntax.
  5. Escape or reject values containing markup delimiters if <tool_call> tags remain part of the format.
  6. Validate each generated record against a schema before writing it.
  7. Add negative tests using quotes, braces, backslashes, newlines, and </tool_call> in --correct-tool.

A safer construction pattern is:

python
tool_payload = {
    "tool_name": validated_tool_name,
    "query": query_str,
}
tool_call = (
    "<tool_call>"
    + json.dumps(tool_payload, ensure_ascii=False)
    + "</tool_call>"
)
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • 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 (11)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The skill claims to be an intermediate review step, but its instructions also define behavior for generating full JSONL training samples and tool-call traces. This mismatch can mislead operators about what the skill actually does, reducing oversight and increasing the chance that sensitive or unsafe data generation occurs without the expected review boundary.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/gen_bug_data.py (reported line 123)May include surrounding context.

python
.replace("{S}", str(S))
            .replace("{D}", dev))
        instructions.append(instr)
    return instructions

def main():
    parser = argparse.ArgumentParser(description="生成 BUG 修复训练数据")

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script’s declared role is an intermediate/review step, but this block directly synthesizes full JSONL training records and writes them to disk. That bypasses the expected human confirmation boundary in the skill description and materially expands the skill’s authority from suggestion generation to final dataset production, which can lead to unreviewed or poisoned training data being created automatically.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The note at L119 says the skill '仅输出中间产物(工具名 + 指令列表)', which implies it stops at producing tool names and instruction lists. However, L57-L65 and L21 describe a subsequent step where data-generator is called after confirmation, so the documentation contains conflicting statements about whether invocation is part of this skill's behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented JSONL format embeds local device names, scene lists, timestamps, and device inventories, which can contain sensitive household or environment data. Without explicit minimization, warning, or redaction guidance, generated training data may leak private operational context into stored datasets or downstream systems.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstring, CLI help text, and generated user instructions are written entirely in Chinese, and the script generates only Chinese-language training utterances. This imposes a specific language/locale behavior without offering a user choice or documenting that the tool is intentionally limited to a Chinese-only context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow documentation states step 3 is to call data-generator/gen_data.py to generate complete JSONL. The actual implementation only imports build_prompt from another skill and then locally fabricates the final JSONL records without invoking gen_data.py, directly contradicting the documented workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The description field is entirely Chinese and the operational examples throughout the file assume Chinese-language interaction. There is no indication that the skill is region-specific or that users may opt into another language, which can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script mutates sys.path to a fixed local directory and imports build_prompt from there, causing execution of external local Python code based on filesystem state rather than a pinned package boundary. If that path is writable or replaceable by another tenant/process, an attacker could achieve arbitrary code execution when this script runs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The script writes generated instructions to a fallback text file and later writes JSONL results to the path provided by --output. Although the argument name implies output, there is no confirmation, overwrite warning, or explanatory comment/docstring about the file-writing side effects at the write sites.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.