Back to skill

Security audit

3d Image Generator

Security checks for vulnerabilities and agentic risk

Overview

The skill can generate images, but it has review-worthy security gaps around local file uploads, API-key handling, and under-disclosed runtime installation.

Review carefully before installing. Use a limited or disposable WeryAI API key, prefer environment injection over persisting the key, avoid passing local files as reference images unless you intend to upload their full contents, and require the agent to disclose exact install commands before adding runtime tooling globally.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.ts:162
Finding

Gateway API Credential Forwarded to Arbitrary Result URLs

Content
View full analysis
{ let lastErr = ""; const transientStatus = (status: number) => status === 408 || status === 429 || status === 502 || status === 503 || status === 504 || (status >= 520 && status <= 599); const transientNetwork = (e: unknown) => { const name = e instanceof Error ? e.name : ""; const msg = e instanceof Error ? e.message : String(e); return ( name === "AbortError" || msg.includes("timeout") || msg.includes("Timeout") || msg.includes("fetch failed") || msg.includes("ECONNRESET") || msg.includes("ETIMEDOUT") || msg.includes("EAI_AGAIN") ); }; const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); for (let attempt = 1; attempt <= DOWNLOAD_MAX_ATTEMPTS; attempt++) { let res: Response | null = null; let threw: unknown = null; for (const useAuth of [false, true] as const) { try { const init: RequestInit = { signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS) }; if (useAuth) { init.headers = { Authorization: `Bearer ${getApiKey()}` }; } res = await fetch(url, init); threw = null; if (res.ok) break; lastErr = `HTTP ${res.status}`; if (!useAuth && (res.status === 401 || res.status === 403)) continue; break; } catch (e) { threw = e; res = null; lastErr = e instanceof Error ? e.message : String(e); if (!useAuth) continue; break; } } ``` ### Technical Analysis The image download URL is taken from the gat ...[truncated 2153 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/main.ts:298
Finding

Arbitrary Local Files Can Be Read and Uploaded as Reference Images

Content
View full analysis
0 ? "/v1/generation/image-to-image" : "/v1/generation/text-to-image"; const body: Record = referenceImages.length > 0 ? { ...baseBody, images: referenceImages.map(toImagePayloadValue) } : baseBody; ``` Validation only checks whether a non-URL path is accessible: ```ts async function validateReferenceImages(paths: string[]): Promise { for (const refPath of paths) { const t = refPath.trim(); if (/^https?:\/\//i.test(t)) continue; const fullPath = path.resolve(refPath); try { await access(fullPath); } catch { throw new Error(`Reference image not found: ${fullPath}`); } } } ``` ### Technical Analysis Any readable filesystem path supplied through `--ref`, the legacy image-to-image interface, or a batch task's `ref` field is read in full, Base64 encoded, and submitted to the WeryAI image-to-image endpoint. The implementation does not: - Restrict local files to the project or an approved media directory. - Verify that the target is a regular file. - Reject symbolic links. - Validate image file signatures. - Enforce an image-only MIME allowlist. - Limit the input size. - Reject known sensitive paths. - Obtain explicit ...[truncated 1589 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.mjs:126
Finding

Persisted API Key Is Written Without Restrictive File Permissions

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/vendor/weryai-image/run-generate.mjs:23
Finding

Unpinned Runtime Package Is Downloaded and Executed

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (92)

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The description is narrower than the code’s actual behavior. While the code can generate 3D-style images via the '3d-render' style preset, its primary implementation is a broad WeryAI image-generation client rather than a specialized 3D rendered art/icon skill. It supports numerous non-3D styles (photoreal, anime, manga, watercolor, infographic, etc.), accepts reference images for image-to-image workflows, processes batch files, exposes status commands, and forwards additional gateway features like webhooks and web search. These are materially broader capabilities than the declared purpose and indicate the description does not accurately represent what the code chunk does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The description is too narrow compared with the code’s actual behavior. While the code does include a '3d-render' style preset, its primary function is not specifically limited to generating 3D rendered art or icons. It is a full-featured gateway client for WeryAI that handles generic text-to-image and image-to-image generation, batch workflows, status checks, retries, downloads, and multiple artistic presets unrelated to 3D. This is a materially broader capability set than the declared purpose, so the description does not accurately represent the code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This code does not generate 3D rendered art, icons, or any visual output. Its sole function is to query a remote balance endpoint and return available credits/balance information. That is a materially different primary purpose from the declared description, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a specialized 3D art generation skill, but the supplied code chunk is only a reusable network client module. Its primary behavior is sending authenticated HTTP requests to a configurable base URL, handling retries/timeouts, and logging sanitized payloads. There is no code here related to 3D rendering, art/icon generation, image synthesis prompts, or style-specific generation. While such a client could support a media-generation skill as infrastructure, this chunk by itself does not accurately represent the declared end-user functionality, so this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is image-generation related, specifically 3D rendered art and icons. However, the supplied code does not generate images, invoke rendering models, process graphics prompts, or contain any 3D/art functionality. Instead, it is a generic support module for interpreting WeryAI API responses and network failures. While such code could be part of a larger image-generation integration, this chunk’s actual behavior is operational error handling rather than 3D graphics generation. That is a materially different primary purpose for this code chunk, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The supplied code does not generate 3D art or icons, nor does it implement rendering, image synthesis, or style-specific graphics behavior. Instead, it is a utility module for processing task metadata and outputs from a backend service. Its primary purpose is workflow/result normalization, including status mapping and output extraction across multiple media types. That is materially different from the declared purpose of a 3D graphics generation skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description says this skill generates 3D rendered art and icons. The supplied code does not generate images or perform any 3D/art rendering behavior. Its primary purpose is to query the status of existing generation tasks or batches from remote API endpoints and report completion/error information. That is a materially different function from the declared purpose, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description suggests a capability focused on creating 3D rendered art/icons. This code chunk does not generate 3D graphics or perform rendering logic. Instead, it is infrastructure code for waiting on remote generation jobs by polling /v1/generation/.../status and batch status endpoints, with retry, timeout, and result normalization behavior. While such polling could support a media-generation system, the code’s actual purpose in this chunk is task-status monitoring, not 3D art creation. The presence of fields like lyrics and coverUrl further indicates broader or different generation domains than the narrowly declared 3D-art skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared purpose says this skill generates 3D rendered art and icons, implying image creation capability focused on a specific visual style. The supplied code does something materially different: it queries an external model registry, validates a mode parameter, and returns lists of available models for text-to-image or image-to-image. There is no image generation, no 3D-specific processing, and no indication of claymorphism, octane, or blender-style rendering. This is a primary-purpose mismatch, not just an implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared purpose is narrowly framed around creating 3D rendered art and icons in certain visual styles. The actual code is a general-purpose image-to-image submission wrapper: it normalizes inputs, validates them, looks up any compatible image_to_image model, builds a request body, and posts to /v1/generation/image-to-image. There is nothing in the code that enforces or specializes for 3D, claymorphism, octane render, blender style, or icon generation. Its primary behavior is broader and materially different from the declared description, so this is a mismatch.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Base URL | `https://api.weryai.com` (hard-coded in `scripts/main.ts`) |

Credential Access

High
Category
Privilege Escalation
Confidence
91% confidence
Finding

The skill instructs the agent to locate, use, and persist IMAGE_GEN_API_KEY in local .env files. Even though it says to treat the key as secret, this is still credential handling and storage logic inside the skill, which increases the chance of accidental disclosure, unsafe file permissions, or persistence of sensitive tokens beyond the user's expectation.

Content

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

md
3. **If `IMAGE_GEN_API_KEY` is missing**, ask the user for permission to configure it now
4. Only after readiness and API key are resolved, continue to model selection / prompt clarification / generation

**Access token**: only use **`IMAGE_GEN_API_KEY`**. It may also live in `.image-skills/3d-image-generator/.env` as `IMAGE_GEN_API_KEY=...`. After the user approves, the agent may persist it there by running `npm run setup -- --project . --workflow <workflow> --persist-api-key` when the key is already in env, or by writing the file locally on the user's behalf instead of asking the user to edit files manually.

**First-use readiness check**: before the first generation run in a new OpenClaw or local instance, the agent must run:

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The code opens and reads a .env file to test whether IMAGE_GEN_API_KEY is present. Directly accessing secret-bearing files is sensitive behavior: even if this implementation only evaluates a regex and does not emit the key, it grants the skill code access to credential material and creates a clear path for future exfiltration or misuse.

Content

Scanner excerpt · scripts/doctor.mjs (reported line 90)May include surrounding context.

js
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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/main.ts (reported line 596)May include surrounding context.

ts
}

function applyStylePreset(prompt: string, style: StylePreset | null | undefined): string {
  if (!style) return prompt;
  return `${prompt.trim()}\n\nStyle preset (${style}): ${STYLE_PRESETS[style]}.`;
}

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/vendor/shared-image-generation/scripts/main.ts (reported line 602)May include surrounding context.

ts
}

function applyStylePreset(prompt: string, style: StylePreset | null | undefined): string {
  if (!style) return prompt;
  return `${prompt.trim()}\n\nStyle preset (${style}): ${STYLE_PRESETS[style]}.`;
}

Credential Access

High
Category
Privilege Escalation
Confidence
76% confidence
Finding

The script handles credential material and writes IMAGE_GEN_API_KEY into a plaintext .env file, which is a credential-management risk. In the context of a 3D image generation skill, storing service credentials is operationally relevant, but plaintext secret persistence remains dangerous because such files are commonly leaked via source control, backups, logs, or local compromise.

Content

Scanner excerpt · scripts/setup.mjs (reported line 33)May include surrounding context.

js
-h, --help            Show help

What this does:
  1) Optionally writes IMAGE_GEN_API_KEY into the local skill .env
  2) Runs doctor (read-only)
  3) Ensures a MODELS.json exists (writes the bundled starter if missing)
  4) Initializes EXTEND.md with Nano Banana 2 if no default model exists yet

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 · scripts/main.ts (reported line 397)May include surrounding context.

ts
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/main.ts (reported line 470)May include surrounding context.

ts
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/main.ts (reported line 471)May include surrounding context.

ts
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/vendor/shared-image-generation/scripts/doctor.mjs (reported line 90)May include surrounding context.

js
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/vendor/shared-image-generation/scripts/main.ts (reported line 403)May include surrounding context.

ts
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/vendor/shared-image-generation/scripts/main.ts (reported line 476)May include surrounding context.

ts
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/vendor/shared-image-generation/scripts/main.ts (reported line 477)May include surrounding context.

ts
const projectSkillDir = path.join(projectRoot, ".image-skills", skillNamespace);
  const homeSkillDir = homeRoot ? path.join(homeRoot, ".image-skills", skillNamespace) : null;

  const projectEnvPath = path.join(projectRoot, ".image-skills", skillNamespace, ".env");
  const projectEnvFile = pathExists(projectEnvPath);
  let apiKeyInProjectEnv = false;
  if (projectEnvFile) {

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 · scripts/doctor.mjs (reported line 284)May include surrounding context.

js
-h, --help            Show help

What this does:
  1) Optionally writes IMAGE_GEN_API_KEY into the local skill .env
  2) Runs doctor (read-only)
  3) Ensures a MODELS.json exists (writes the bundled starter if missing)
  4) Initializes EXTEND.md with Nano Banana 2 if no default model exists yet

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 · scripts/main.ts (reported line 571)May include surrounding context.

ts
-h, --help            Show help

What this does:
  1) Optionally writes IMAGE_GEN_API_KEY into the local skill .env
  2) Runs doctor (read-only)
  3) Ensures a MODELS.json exists (writes the bundled starter if missing)
  4) Initializes EXTEND.md with Nano Banana 2 if no default model exists yet

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.potential_exfiltration

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/bootstrap.mjs:86

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/doctor.mjs:56

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/smoke-check.mjs:18

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/shared-image-generation/scripts/bootstrap.mjs:86

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/shared-image-generation/scripts/doctor.mjs:56

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/shared-image-generation/scripts/smoke-check.mjs:18

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/weryai-image/discover-models.mjs:9

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/weryai-image/doctor.mjs:9

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/weryai-image/main.ts:14

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/weryai-image/recommend-model.mjs:9

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/weryai-image/run-generate.mjs:23

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/vendor/weryai-image/setup.mjs:9

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/main.ts:47

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/vendor/shared-image-generation/scripts/main.ts:51

File read combined with network send (possible exfiltration).

Warn
Code
suspicious.potential_exfiltration
Location
scripts/main.ts:6

File read combined with network send (possible exfiltration).

Warn
Code
suspicious.potential_exfiltration
Location
scripts/vendor/shared-image-generation/scripts/main.ts:6