Back to skill

Security audit

Character Image Generator

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is mostly coherent, but it needs Review because its runtime can upload arbitrary readable local files as reference images and has unsafe API-key handling around downloads.

Review before installing. Use this only with trusted prompts and batch files, avoid passing local paths as references unless you intend to upload that exact file to WeryAI, prefer an environment variable over persisted key storage on shared machines, and use a trusted installed Bun runtime rather than automatic npx execution where possible.

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:187
Finding

WeryAI API Key Can Be Disclosed to an Untrusted Image Result URL

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/main.ts:298
Finding

Arbitrary Readable Local Files Can Be Uploaded as Reference Images

Content
View full analysis
{ 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}`); } } } ``` The resulting content is transmitted to the gateway: ```ts const body: Record = referenceImages.length > 0 ? { ...baseBody, images: referenceImages.map(toImagePayloadValue), } : baseBody; ``` ### Technical Analysis Any process-readable path supplied as a reference image is resolved and read without enforcing project-directory containment. The implementation does not verify that the path refers to a regular image file, reject symbolic links, validate file signatures, or impose a maximum file size. A non-image file receives `application/octet-stream` based on its extension and is still encoded as a `data:` URL and placed in the network request. Therefore, credentials, source files, SSH private keys, configuration files, or other sensitive data can be transmitted to ...[truncated 1392 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/setup.mjs:124
Finding

Persisted API Key Files Are Not Created with Owner-Only Permissions

Content
View full analysis
Write IMAGE_GEN_API_KEY into local skill config ``` ```js else if (current === "--api-key") { args.apiKey = argv[++i] ?? null; } ``` ### Technical Analysis The API key is stored in plaintext under a project or home `.image-skills/.../.env` path. The directory and file are created without explicit restrictive modes. Their effective permissions therefore depend on the process umask and any pre-existing filesystem state. The code also does not repair unsafe permissions on an existing `.env` file. On shared systems, a permissive umask or previously created file can make the credential readable by other local users or processes. Accepting a secret through `--api-key ` creates an additional disclosure surface because command-line arguments may be recorded in shell history, process listings, audit logs, or automation logs. ### Attack Path 1. A user invokes setup with `--persist-api-key` or `--api-key`. 2. Setup creates or updates `.image-skills/character-image-generator/.env`. 3. The file inherits default permissions or retains existing permissive permissions. 4. Another local account or process with filesystem access reads the file. 5. Alternatively, the secret supplied through `--api-key` is recovered from shell hi ...[truncated 491 chars]
Remediation
View remediation
`. 7. Accept secrets through a protected environment variable, terminal prompt with echo disabled, or standard input. 8. Warn users that environment-backed persistence writes a plaintext credential. 9. Prefer an operating-system credential store where available. 10. Apply the same permission controls to the duplicated vendored setup implementation. ]]>

T08 · Insecure Dependencies

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

Unpinned Bun Package Is Downloaded and Executed Automatically

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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
Findings (96)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

Handling outputs for videos, audio, lyrics, and cover URLs indicates the runtime may process broader media task types than the character-image description implies. In a narrowly scoped skill ecosystem, that capability expansion matters because it increases the attack surface and may route user data through code paths that were never expected or reviewed for this skill.

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/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
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 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/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) {

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code accepts an arbitrary --webhook-url and forwards it directly to the upstream generation API. For a character-image generator, this creates an unnecessary outbound callback channel that could be abused to exfiltrate metadata, interact with attacker-controlled endpoints, or enable SSRF-like behavior via the third-party service acting on behalf of the user environment.

Content

No source excerpt is available for this finding.

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

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/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