Back to skill

Security audit

SynthClaw

Security checks for vulnerabilities and agentic risk

Overview

This skill mostly matches its Blender rendering purpose, but it needs review because it can run Blender on local files, inherit the full environment, and delete TIFF files broadly under a chosen output folder.

Install only if you are comfortable letting it run Blender locally. Use trusted .blend files, run it in a constrained environment when possible, avoid passing secrets through the environment, and always choose a fresh dedicated output directory so unrelated TIFF files cannot be deleted.

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

T09 · Insecure Skill Coding Practices

Warning
Location
src/synthclaw/blender/cleanup.py:3
Finding

Recursive Deletion of Unrelated TIFF Files in User-Controlled Output Directory

Content
View full analysis

Vulnerability Details

File Location: src/synthclaw/blender/cleanup.py:3-12
Call Site: scripts/render_dataset.py:57-59
Vulnerability Type: Unrestricted destructive file cleanup
Risk Level: Medium

Vulnerable Code

python
def clean_up_tifs(output_dir):
    """
    Walks the output directories and removes unnecessary .tif files.
    """
    for root, dirs, files in os.walk(output_dir):
        for file in files:
            if file.endswith('.tif'):
                try:
                    os.remove(os.path.join(root, file))
                    print(f"[SynthClaw] CleanUp: Deleted temporary TIFF file {os.path.join(root, file)}")
                except Exception as e:
                    print(f"[SynthClaw] CleanUp: Failed to delete TIFF file {file}: {e}")

The function is invoked after dataset rendering:

python
print("\n--- [SynthClaw] Render Loop Complete. Cleaning up files... ---")
clean_up_tifs(output_dir)
print("[SynthClaw] Complete!")

Technical Analysis

render_procedural_dataset accepts a caller-selected output_dir, which may be an existing directory containing user data. After rendering, clean_up_tifs recursively traverses that entire directory tree and deletes every file whose name ends with lowercase .tif.

The cleanup routine does not establish that a file:

  • Was generated by the current render operation.
  • Is a temporary artifact.
  • Resides in a dedicated per-run directory.
  • Matches a tracked list of expected render outputs.
  • Is safe to delete after resolving symbolic links and canonical paths.

Consequently, the cleanup operation has a broader deletion scope than required by the rendering task. It treats all matching files under the output tree as temporary, including unrelated pre-existing TIFF images.

Attack Path

  1. An attacker, untrusted agent instruction, or accidental user input selects an existing directory as ` ...[truncated 1461 chars]
Remediation
View remediation

Remediation Suggestions

Replace extension-based recursive cleanup with explicit artifact tracking:

  1. Record the exact paths of temporary files created during the current render operation.
  2. Delete only paths contained in that trusted collection.
  3. Canonicalize each candidate with os.path.realpath and verify confinement using os.path.commonpath.
  4. Reject candidates outside a dedicated per-run temporary directory.
  5. Create each render in a new directory using tempfile.mkdtemp, then move only intended final outputs to the user-selected destination.
  6. Avoid recursively cleaning a pre-existing user directory.
  7. If broad cleanup remains necessary, require explicit opt-in and return the candidate file list for confirmation before deletion.
  8. Report cleanup failures and deleted paths through the API result rather than only printing them.

A safer design is:

python
def clean_up_generated_files(output_dir, generated_temp_files):
    output_root = os.path.realpath(output_dir)

    for candidate in generated_temp_files:
        candidate_path = os.path.realpath(candidate)

        if os.path.commonpath([output_root, candidate_path]) != output_root:
            raise ValueError(f"Cleanup path escapes output directory: {candidate}")

        if os.path.isfile(candidate_path):
            os.remove(candidate_path)

The generated_temp_files collection must be populated when the renderer creates each temporary artifact, rather than reconstructed by recursively searching for a filename extension.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description emphasizes metric-producing synthetic data generation and optimization feedback, with rendering support across CYCLES and EEVEE. The supplied code only acts as a narrow Blender bridge: it parses command-line numeric parameters, updates material value nodes, configures the render engine through imported helpers, and prints status. While engine configuration is consistent with part of the description, the most important advertised capabilities—render execution, Naturalness/LPIPS reporting, Shannon entropy diversity measurement, and iterative optimization feedback—are absent from this code chunk. This is a material description-versus-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description centers on a rendering/generation skill with feedback metrics for optimization. The supplied code instead functions as a Blender scene inspection and heuristic complexity analysis tool. It enumerates VALUE nodes that could potentially be manipulated later, but it does not actually change parameters, render outputs, calculate perceptual quality metrics, or measure dataset diversity. Additionally, it extracts detailed scene structure (collections, objects, transforms, materials), which is an undeclared introspection capability and not merely an implementation detail of rendering. Therefore the code's actual behavior is materially different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description promises a synthetic-data rendering skill with metric-driven feedback and engine support for both CYCLES and EEVEE. The supplied code is much narrower: it builds and saves a minimal Blender test scene with one agent-controllable shader value and basic EEVEE settings. While the controllable node and EEVEE configuration loosely relate to the description, the core advertised capabilities—rendering outputs, quality metrics, diversity analysis, and optimization loop—are absent. This is a material mismatch in primary purpose and functionality, not merely an incomplete implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The code clearly implements Blender-based synthetic dataset rendering with configurable randomizations and output routing, which is broadly aligned with the rendering portion of the description. However, the declared description emphasizes a key capability: dynamic quality metrics (Naturalness and LPIPS), dataset-wide diversity measurement (Shannon entropy), and use of those metrics to guide iterative optimization. None of those behaviors appear in the supplied code. The script only reads configuration, applies randomization, renders images, and cleans up files. Because the metrics-and-optimization functionality is presented as a key capability but is absent from the actual behavior, the description materially overstates what this code chunk does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The description centers on rendering Blender scenes for synthetic data generation and returning multiple guidance metrics during generation, including Naturalness, LPIPS, and diversity. The supplied code instead analyzes a Blender file by launching Blender with a separate analysis script and computes post hoc metrics over provided image paths. While Shannon entropy/diversity and Naturalness are partially aligned with the description, the primary claimed functionality—rendering with controllable procedural parameters and engine support—is absent, and LPIPS is missing entirely. This is a material description-to-behavior mismatch rather than a minor implementation gap.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises substantial functionality related to Blender rendering and metric-driven synthetic data optimization. However, the provided code chunk is effectively empty aside from a package comment, so none of the described capabilities are present in the supplied implementation. This is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description centers on Blender rendering for synthetic data generation plus metric reporting and optimization guidance. The supplied code chunk does not implement any of those core behaviors; instead, it performs filesystem cleanup by deleting TIFF files under an output directory. While cleanup could be a supporting detail in a larger rendering pipeline, this chunk's actual behavior is materially different from the declared primary purpose and includes an undeclared file-deletion capability. Therefore this chunk is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description emphasizes synthetic-data rendering with metric-driven evaluation and optimization capabilities. The supplied code chunk does not implement any of those core behaviors. Instead, it performs compositor housekeeping inside Blender: creating a missing Composite node, routing File Output nodes to derived subfolders, and forcing output formats to PNG. While this may be a supporting part of a rendering pipeline, it does not match the description's highlighted capabilities, especially the dynamic quality metrics and dataset diversity measurement. Therefore the code chunk is materially narrower and behaviorally different from the declared purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description emphasizes a full synthetic-data rendering capability with controllable procedural parameters, render-engine support, and especially dynamic evaluation metrics used to guide iterative optimization. The provided code chunk implements only one supporting part of that pipeline: randomizing Blender scene/material/camera/light properties from configured distributions. It does not render Blender files, select or manage CYCLES/EEVEE, compute Naturalness/LPIPS/Shannon entropy, or return metric results. Therefore the code chunk materially underdelivers relative to the declared purpose, making the description inaccurate for this supplied code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The core rendering claim is accurate: the code runs Blender headlessly, passes procedural parameters, supports CYCLES and EEVEE, and includes convenience wrappers for fast and production rendering. The optional metrics portion is only partially aligned: it can compute naturalness-related values via granatpy and LPIPS against a reference image, but only when compute_metrics is enabled and the dependencies are installed. However, a key declared capability—measuring dataset-wide diversity via Shannon entropy—is absent. The dataset rendering function simply renders multiple images from a config and returns logs; no entropy or diversity analysis is performed. The description also suggests agents can iteratively optimize parameter ranges based on returned metrics, but the code itself provides no optimization loop or parameter-range adaptation logic; it only exposes render and metric primitives. Additionally, the code includes an undeclared analyze_blend capability that inspects .blend files for available parameters. Because the description emphasizes a key metric capability that is materially missing, this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The code broadly aligns with the Blender procedural rendering and dataset generation description: it analyzes blend files, renders parameterized scenes/datasets, and tests both EEVEE and CYCLES. It also includes dataset analysis with a naturalness-related metric and diversity output, which partially matches the declared optimization/metrics story. However, the description makes specific claims about returning LPIPS and measuring diversity via Shannon entropy, and those specifics are not supported by this code chunk. The test only validates 'naturalness_mean', a generic 'diversity' float, and per-image metrics; there is no evidence of LPIPS or explicit Shannon entropy. Additionally, the code demonstrates extra capabilities not mentioned in the description, including JPEG format conversion and specialized compositing/mask outputs for plaque/well rendering. Because the description contains materially specific metric claims not substantiated by the code and omits notable tested capabilities, this is a mismatch.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
94% confidence
Finding

Copying the full parent environment into a child process that opens untrusted .blend content can expose sensitive variables such as API keys, cloud credentials, proxy settings, and tokens to Blender or any Python code/plugins it triggers. In this skill's context, the danger is elevated because it explicitly processes agent-supplied files and parameters through a large external application capable of executing complex logic.

Content

Scanner excerpt · src/synthclaw/blender_skill.py (reported line 103)May include surrounding context.

python
param_args = [f"{k}={v}" for k, v in parameters.items()]
    
    # Pass engine and samples to the Blender script via environment variables
    env = os.environ.copy()
    env["SYNTHCLAW_PACKAGE_PATH"] = os.path.abspath(os.path.join(MODULE_DIR, ".."))
    env["BLENDER_ENGINE"] = engine
    env["BLENDER_SAMPLES"] = str(samples)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
94% confidence
Finding

This repeats the same issue in the dataset-rendering path: the entire host environment is forwarded to Blender while processing potentially untrusted content at larger scale. Because dataset generation may run longer and over more files, it increases the exposure window and the likelihood that child code can inspect or misuse inherited secrets.

Content

Scanner excerpt · src/synthclaw/blender_skill.py (reported line 376)May include surrounding context.

python
script_path = os.path.join(SCRIPTS_DIR, "render_dataset.py")
        
        # Pass engine and samples to the Blender script via environment variables
        env = os.environ.copy()
        env["SYNTHCLAW_PACKAGE_PATH"] = os.path.abspath(os.path.join(MODULE_DIR, ".."))
        env["BLENDER_ENGINE"] = engine
        env["BLENDER_SAMPLES"] = str(samples)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README frames invocation in broad natural-language terms such as letting an LLM 'autonomously manipulate' Blender parameters and trigger renders, but it does not define clear allowed intents, scope limits, or guardrails for when the skill should be invoked. In an agentic environment, ambiguous trigger boundaries can cause unintended execution on the wrong assets, repeated expensive renders, or use on sensitive local files because the agent is encouraged to infer capability from prose rather than explicit policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README emphasizes autonomous node updates and render generation, but does not clearly warn that the process changes Blender scene state and writes image or analysis outputs to disk. In a local agent setting, that omission is security-relevant because users or orchestrators may treat the skill as read-only analysis while it can mutate project data, overwrite outputs, consume storage, or persist derived information from sensitive scenes.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill exposes capabilities consistent with environment access, file read/write, and shell execution, but the manifest does not declare any tool scope such as explicit permissions or allowed-tools. In an agent setting, this weakens policy enforcement and can let the skill be invoked with broader authority than a reviewer or orchestrator would expect, increasing the risk of unintended command execution or filesystem access.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script trusts the SYNTHCLAW_PACKAGE_PATH environment variable and appends it to sys.path before importing synthclaw modules. An attacker who can influence the environment can point this path to malicious code and achieve arbitrary Python code execution inside Blender when the imports occur, which exceeds the skill’s stated purpose of rendering parameter control.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest emphasizes dynamic quality metrics such as Naturalness, LPIPS, and dataset-wide diversity, but this file does not compute any such metrics. Instead, it gathers Blender scene internals like collections, object transforms, materials, and a hand-written complexity rating, which is materially different from the described rendering-quality analysis.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The docstring promises 'realism metrics and available Value Nodes as JSON,' yet the code computes only a basic complexity score based on polygons, materials, lights, and render engine. No recognized realism metric is calculated, so the inline documentation actively overstates what the function does.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script unconditionally selects and deletes all existing Blender objects in the current scene before creating test content. If run in an open user project or automation context, this can destroy work or corrupt the expected scene state without warning, backup, or isolation. In this skill’s context, the danger is increased because agent-driven rendering workflows may execute scripts automatically, making accidental destructive use more likely.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The code launches the external Blender executable on an agent-supplied .blend file, which is a risky trust boundary because Blender files can embed Python, drivers, and other behaviors that may execute or trigger unsafe processing in a powerful native application. Even though subprocess.run is invoked without shell=True, the danger here is not shell injection but arbitrary code execution or hostile file parsing through Blender itself, especially in an agent workflow that may analyze untrusted assets automatically.

Content

Scanner excerpt · src/synthclaw/analyze_skill.py (reported line 20)May include surrounding context.

python
]

    try:
        result = subprocess.run(command, capture_output=True, text=True, check=True)
        # Parse output between markers
        output = result.stdout
        if "---ANALYSIS_START---" in output and "---ANALYSIS_END---" in output:

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The manifest description highlights returning dynamic quality metrics including both Naturalness and LPIPS, plus dataset-wide diversity. In this file, analyze_dataset computes Shannon entropy and Naturalness only; there is no LPIPS computation or return value, creating a mismatch between the described capability and the implemented behavior here.

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 · src/synthclaw/blender_skill.py (reported line 23)May include surrounding context.

python
"""
    # Use start_new_session=True to run in a separate process group on Unix.
    # This ensures that Blender and any spawned child processes are killed on timeout.
    proc = subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The docstring for analyze_blender_file says "OpenClaw Skill," while the manifest identifies this skill as synthclaw. This is an active documentation inconsistency about the component's identity and intent, which can mislead reviewers about what code they are auditing.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.