Back to skill

Security audit

Meshy Openclaw

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a legitimate Meshy API helper, but it has avoidable API-key handling and disclosure issues that should be reviewed before installation.

Install only if you are comfortable giving the agent access to a Meshy API key and sending your prompts or image URLs to Meshy. Prefer a session environment variable over saving the key in `.env`, and remove or change the snippets that print any part of the key before use.

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

Warning
Location
SKILL.md:88
Finding

Partial API Credential Disclosure Through Console Logging

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 88–102 and 240–241
Vulnerability Type: Partial secret exposure through terminal and agent logs
Risk Level: Medium

Vulnerable Code

bash
# 1. Check current env var
if [ -n "$MESHY_API_KEY" ]; then
  echo "ENV_VAR: FOUND (${MESHY_API_KEY:0:8}...)"
else
  echo "ENV_VAR: NOT_FOUND"
fi

# 2. Check .env in current working directory only
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): FOUND"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"'"'" )
fi

# 3. Final status
if [ -n "$MESHY_API_KEY" ]; then
  echo "READY: key=${MESHY_API_KEY:0:8}..."
else
  echo "READY: NO_KEY_FOUND"
fi

The reusable Python template also exposes the same token prefix:

python
# Never log the full key — only first 8 chars for traceability
print(f"API key loaded: {API_KEY[:8]}...")

Technical Analysis

The Skill intentionally prints the first eight characters of MESHY_API_KEY after reading it from either the process environment or the current directory's .env file. This contradicts the security manifest's assertion that the credential is never logged.

Terminal output generated by an agent may be retained in conversation transcripts, CI logs, shell histories, observability systems, or debugging records. Although the full bearer token is not exposed, revealing a stable prefix unnecessarily discloses credential material and allows an observer to identify or correlate a particular token across systems and sessions.

The disclosure is not necessary to verify that the key was loaded. A boolean result provides the same operational value without exposing any part of the secret.

Attack Path

  1. A user or automation environment supplies MESHY_API_KEY through the environment or .env.
  2. The Skill executes its mandatory API-key detection ...[truncated 1190 chars]
Remediation
View remediation

Remediation Suggestions

  • Never print any substring of an API key, including prefixes intended for traceability.

  • Replace both shell messages with non-sensitive status output:

    bash
    if [ -n "$MESHY_API_KEY" ]; then
      echo "ENV_VAR: FOUND"
    else
      echo "ENV_VAR: NOT_FOUND"
    fi
    
    if [ -n "$MESHY_API_KEY" ]; then
      echo "READY: API_KEY_LOADED"
    else
      echo "READY: NO_KEY_FOUND"
    fi
    
  • Replace the Python log statement with:

    python
    print("API key loaded")
    
  • Ensure exception messages, HTTP debugging, and request tracing do not serialize the Authorization header.

  • Add automated secret-redaction tests that fail if output contains any portion of a configured test token.

  • Update the security manifest only after all token-prefix logging has been removed.

T08 · Insecure Dependencies

Note
Location
SKILL.md:108
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 15 and 108–117
Vulnerability Type: Unconstrained package installation and supply-chain exposure
Risk Level: Low

Vulnerable Code

The installation metadata specifies the dependency without a version constraint:

yaml
install:
  - kind: uv
    package: requests

The runtime instructions also recommend installing the mutable latest release:

bash
python3 -c "import requests; print('PYTHON_REQUESTS: OK')" 2>/dev/null || echo "PYTHON_REQUESTS: MISSING (run: pip install requests)"
text
- **Python requests missing** → Run `pip install requests`.

Technical Analysis

The Skill depends on the legitimate requests package, but neither the package metadata nor the fallback installation command constrains its version or verifies package integrity. As a result, installation behavior depends on whichever release and package-index state exist at execution time.

This weakens reproducibility and expands the supply-chain trust boundary. If the configured package index, dependency resolution process, or a future package release is compromised, installation can introduce attacker-controlled code. Python packages and their transitive dependencies may execute code during installation or later when imported by the generated workflow.

The finding does not establish that the current requests package is malicious. It identifies an avoidable supply-chain weakness caused by resolving and executing mutable dependency versions.

Attack Path

  1. The target environment does not already contain the requests module.
  2. Following the Skill instructions, the agent runs pip install requests, or the Skill manager resolves the unconstrained package declaration.
  3. The installer queries the configured Python package index and selects the current compatible release and transitive dependencies.
  4. If the index, resolution configuration, ...[truncated 933 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin requests to a reviewed version or narrow compatible range in the installation metadata.

  • Replace the unconstrained command with a version-pinned installation, for example:

    bash
    python3 -m pip install "requests==REVIEWED_VERSION"
    
  • Maintain a lockfile containing all transitive dependency versions.

  • Use hash verification, such as pip install --require-hashes -r requirements.txt, where supported.

  • Install only from an explicitly trusted package index over TLS.

  • Prefer a project-local virtual environment rather than modifying the global interpreter environment.

  • Periodically review and deliberately update pinned dependencies after vulnerability and integrity checks.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (51)

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 94)May include surrounding context.

md
echo "ENV_VAR: NOT_FOUND"
fi

# 2. Check .env in current working directory only
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): FOUND"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"'"'" )

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 221)May include surrounding context.

md
echo "ENV_VAR: NOT_FOUND"
fi

# 2. Check .env in current working directory only
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): FOUND"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"'"'" )

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 95)May include surrounding context.

md
fi

# 2. Check .env in current working directory only
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): FOUND"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"'"'" )
fi

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 97)May include surrounding context.

md
fi

# 2. Check .env in current working directory only
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): FOUND"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"'"'" )
fi

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · SKILL.md (reported line 225)May include surrounding context.

md
fi

# 2. Check .env in current working directory only
if [ -f ".env" ] && grep -q "MESHY_API_KEY" ".env" 2>/dev/null; then
  echo "DOTENV(.env): FOUND"
  export MESHY_API_KEY=$(grep "^MESHY_API_KEY=" ".env" | head -1 | cut -d'=' -f2- | tr -d '"'"'" )
fi

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

The skill instructs persisting a sensitive API key into a plaintext .env file in the project directory. Although common, writing secrets to disk increases exposure to local compromise, accidental inclusion in archives, or later misuse by other tools operating in the repository.

Content

Scanner excerpt · SKILL.md (reported line 155)May include surrounding context.

To persist the key (current project only):

bash
# Write to .env in current working directory
echo 'MESHY_API_KEY=msy_PASTE_KEY_HERE' >> .env
echo "Saved to .env"

Credential Access

High
Category
Privilege Escalation
Confidence
87% confidence
Finding

Saving the API key to .env creates durable plaintext secret storage in the workspace. In shared or synced project directories, this can expose credentials beyond the immediate session and increase the blast radius of a leak.

Content

Scanner excerpt · SKILL.md (reported line 156)May include surrounding context.

bash
# Write to .env in current working directory
echo 'MESHY_API_KEY=msy_PASTE_KEY_HERE' >> .env
echo "Saved to .env"

# IMPORTANT: add .env to .gitignore to avoid leaking the key

Credential Access

High
Category
Privilege Escalation
Confidence
84% confidence
Finding

The combined instruction to store the key in .env and then manage .gitignore acknowledges the risk but still normalizes plaintext credential storage. This is dangerous because users may assume .gitignore fully mitigates secret exposure when it does not protect against local access, backups, or copy operations.

Content

Scanner excerpt · SKILL.md (reported line 157)May include surrounding context.

bash
# Write to .env in current working directory
echo 'MESHY_API_KEY=msy_PASTE_KEY_HERE' >> .env
echo "Saved to .env"

# IMPORTANT: add .env to .gitignore to avoid leaking the key
grep -q "^\.env" .gitignore 2>/dev/null || echo ".env" >> .gitignore

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The .gitignore mitigation does not eliminate the core risk introduced by writing credentials to .env; it only reduces one exfiltration path. Users may be given a false sense of safety while the secret remains plainly accessible on disk.

Content

Scanner excerpt · SKILL.md (reported line 159)May include surrounding context.

echo 'MESHY_API_KEY=msy_PASTE_KEY_HERE' >> .env echo "Saved to .env"

IMPORTANT: add .env to .gitignore to avoid leaking the key

grep -q "^.env" .gitignore 2>/dev/null || echo ".env" >> .gitignore echo ".env added to .gitignore"

text

Credential Access

High
Category
Privilege Escalation
Confidence
82% confidence
Finding

The guidance that .env has been added to .gitignore can imply the stored credential is now safe, despite continued exposure to local reads and non-git distribution channels. This is insecure secret-management advice in a skill that handles API authentication.

Content

Scanner excerpt · SKILL.md (reported line 160)May include surrounding context.

echo "Saved to .env"

IMPORTANT: add .env to .gitignore to avoid leaking the key

grep -q "^.env" .gitignore 2>/dev/null || echo ".env" >> .gitignore echo ".env added to .gitignore"

text

Credential Access

High
Category
Privilege Escalation
Confidence
81% confidence
Finding

The security reminder still endorses storing the API key in plaintext within the project, which is a weak secret-management pattern. In agent-driven environments, workspace files may be more broadly accessible than users expect, making persisted credentials more sensitive than in manual workflows.

Content

Scanner excerpt · SKILL.md (reported line 161)May include surrounding context.

IMPORTANT: add .env to .gitignore to avoid leaking the key

grep -q "^.env" .gitignore 2>/dev/null || echo ".env" >> .gitignore echo ".env added to .gitignore"

text

> **Security reminder:** The key is stored only in `.env` in your current project directory. Never commit this file to version control. `.env` has been automatically added to `.gitignore`.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 288)May include surrounding context.

md
Returns the full task object including `status`, `progress`, `model_urls`, `texture_urls`.

### DELETE /openapi/v2/text-to-3d/:id — Delete Task

Permanently deletes a task and all associated data.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 363)May include surrounding context.

md
**Response:** `{"result": "<task_id>"}`

### GET /openapi/v1/image-to-3d/:id — Retrieve Task
### DELETE /openapi/v1/image-to-3d/:id — Delete Task
### GET /openapi/v1/image-to-3d — List Tasks
### GET /openapi/v1/image-to-3d/:id/stream — Stream Task

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 383)May include surrounding context.

md
**Response:** `{"result": "<task_id>"}`

### GET /openapi/v1/multi-image-to-3d/:id — Retrieve Task
### DELETE /openapi/v1/multi-image-to-3d/:id — Delete Task
### GET /openapi/v1/multi-image-to-3d — List Tasks
### GET /openapi/v1/multi-image-to-3d/:id/stream — Stream Task

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 414)May include surrounding context.

md
**Response:** `{"result": "<task_id>"}`

### GET /openapi/v1/remesh/:id — Retrieve Task
### DELETE /openapi/v1/remesh/:id — Delete Task
### GET /openapi/v1/remesh — List Tasks
### GET /openapi/v1/remesh/:id/stream — Stream Task

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 441)May include surrounding context.

md
**Response:** `{"result": "<task_id>"}`

### GET /openapi/v1/retexture/:id — Retrieve Task
### DELETE /openapi/v1/retexture/:id — Delete Task
### GET /openapi/v1/retexture — List Tasks
### GET /openapi/v1/retexture/:id/stream — Stream Task

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 473)May include surrounding context.

md
- `basic_animations.running_glb_url`, `running_fbx_url`, `running_armature_glb_url`

### GET /openapi/v1/rigging/:id — Retrieve Task
### DELETE /openapi/v1/rigging/:id — Delete Task
### GET /openapi/v1/rigging/:id/stream — Stream Task

---

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 502)May include surrounding context.

md
- `processed_usdz_url`, `processed_armature_fbx_url`, `processed_animation_fps_fbx_url`

### GET /openapi/v1/animations/:id — Retrieve Task
### DELETE /openapi/v1/animations/:id — Delete Task
### GET /openapi/v1/animations/:id/stream — Stream Task

---

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 525)May include surrounding context.

md
**Response:** `{"result": "<task_id>"}`

### GET /openapi/v1/text-to-image/:id — Retrieve Task
### DELETE /openapi/v1/text-to-image/:id — Delete Task
### GET /openapi/v1/text-to-image — List Tasks
### GET /openapi/v1/text-to-image/:id/stream — Stream Task

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · reference.md (reported line 548)May include surrounding context.

md
**Response:** `{"result": "<task_id>"}`

### GET /openapi/v1/image-to-image/:id — Retrieve Task
### DELETE /openapi/v1/image-to-image/:id — Delete Task
### GET /openapi/v1/image-to-image — List Tasks
### GET /openapi/v1/image-to-image/:id/stream — Stream Task

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The description says to use the skill when the user asks to 'create 3D models' or 'interact with the Meshy API,' which are broad activation conditions without clear constraints or exclusion examples. In environments with automatic skill routing, this could cause the skill to trigger for generic modeling questions or non-Meshy requests.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest claims the skill only writes .env and meshy_output/, but later instructions also write to .gitignore. This discrepancy undermines trust boundaries and can cause an agent or reviewer to approve behavior under false assumptions about filesystem scope.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The detection step echoes the first bytes of MESHY_API_KEY to output, which exposes part of a secret token in logs, transcripts, or UI surfaces. Partial secret disclosure weakens credential hygiene and can aid correlation, validation, or targeted theft when logs are accessible to other users or systems.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill instructs modification of .gitignore, which is outside its declared file access scope and not essential to performing Meshy API operations. While the change is security-motivated, it expands the skill’s write surface into project metadata and creates a mismatch between declared and actual behavior.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The runtime script prints a masked prefix of the loaded API key, creating avoidable credential exposure in command output and persisted logs. Even truncated tokens are sensitive metadata and should not be emitted during routine execution.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.