Back to skill

Security audit

Nano Banana Pro OpenRouter

Security checks for vulnerabilities and agentic risk

Overview

This image-generation skill is purpose-aligned but handles API keys unsafely and can send credentials and prompts to an endpoint controlled through local environment files.

Review this skill carefully before installing. It should be changed to avoid agent-readable .env secrets, avoid --api-key command-line passing, stop loading .env from the caller's current directory, restrict OPENROUTER_BASE_URL to the intended OpenRouter endpoint unless explicitly approved, and validate downloaded image URLs. There is no clear evidence of intentional malware, but the current credential and endpoint handling can expose an OpenRouter key and user prompts.

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

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:67
Finding

API Key Exposure Through Agent Context and Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:67-70
Vulnerability Type: Unnecessary secret access and insecure credential transmission
Risk Level: High

Vulnerable Code

text
- If `~/.openclaw/workspace/skills/nano-banana-pro-openrouter/.env` exists:
  1. Use the `read` tool to read `.env`
  2. Extract `OPENROUTER_API_KEY` and `OPENROUTER_BASE_URL`
  3. Always pass the key via `--api-key` when running the script

Technical Analysis

The Skill explicitly instructs the Agent to read a credential file, extract the OpenRouter API key into the Agent's context, and pass that secret as a command-line argument.

This access exceeds the minimum privileges needed for image generation. The shell script already loads the Skill-local .env file itself, so the Agent does not need to read or process the secret. Passing the key using --api-key may additionally expose it through process listings, command logging, execution telemetry, shell history, or tool-call records.

Attack Path

  1. A plaintext API key is stored in the Skill's .env file.
  2. The Skill instructions direct the Agent to read the entire file.
  3. The API key enters the Agent and tool execution context.
  4. The Agent invokes the script with --api-key KEY.
  5. The key may become visible in process arguments, tool logs, execution history, or diagnostic output.
  6. A party with access to any of these channels can recover and reuse the credential.

Impact Assessment

Successful exploitation may disclose the OpenRouter API key to other local users, monitoring systems, logs, or parties with access to Agent execution records. A stolen key could be used to consume the victim's API quota, incur charges, or access capabilities associated with the affected OpenRouter account. This does not directly grant operating-system privilege escalation.

Remediation
View remediation

Remediation Suggestions

  • Remove the instructions requiring the Agent to read .env.
  • Do not pass API keys through command-line arguments.
  • Allow the script to read only its trusted Skill-local .env, which it already supports.
  • Alternatively, supply credentials through a protected file descriptor, standard input, or a dedicated secret manager.
  • Ensure the credential file has restrictive permissions, such as mode 0600.
  • Redact authorization data from all execution logs and error reports.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_image.sh:139
Finding

Working-Directory Environment Poisoning Can Redirect API Credentials

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.sh:139-154
Vulnerability Type: Untrusted configuration loading and credential exfiltration
Risk Level: High

Vulnerable Code

sh
load_env_file "$PWD/.env"
load_env_file "$skill_dir/.env"

if [ -z "$api_key" ]; then
  api_key=${OPENROUTER_API_KEY:-}
fi

if [ -z "$api_key" ]; then
  echo "Error: No API key provided." >&2
  echo "Please either:" >&2
  echo "  1. Provide --api-key argument" >&2
  echo "  2. Set OPENROUTER_API_KEY environment variable" >&2
  exit 1
fi

base_url=${OPENROUTER_BASE_URL:-}

The loaded variables are subsequently used in the authenticated request:

sh
curl -sS -o "$response_file" -w "%{http_code}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $api_key" \
  -d "$payload" \
  "$base_url"

Technical Analysis

The script automatically loads .env from the caller's current working directory before loading the Skill-local configuration. The environment loader preserves variables that are already set, so values from $PWD/.env take precedence over corresponding values in the Skill-local file.

The documentation instructs callers to execute the script using an absolute path without changing into the Skill directory. As a result, the current working directory may be unrelated to the Skill and potentially attacker-controlled.

OPENROUTER_BASE_URL is accepted without validating its scheme, hostname, or relationship to OpenRouter. An attacker-controlled .env can therefore redirect the authenticated request to an arbitrary endpoint. If the API key comes from an existing environment variable, a command-line argument, or another configuration source, the script sends that key and the user's prompt to the attacker-selected server.

Attack Path

  1. An attacker gains write access to the directory from which the user or Agent invokes the Skill.

...[truncated 940 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove automatic loading of $PWD/.env.
  • Load configuration only from a fixed, trusted Skill directory or a user-selected path with verified ownership and restrictive permissions.
  • Require an HTTPS endpoint.
  • Allowlist the expected OpenRouter hostname and full API path by default.
  • Require explicit, informed user authorization before permitting a custom API endpoint.
  • Reject URLs containing unexpected credentials, ports, fragments, or schemes.
  • Keep the API key out of command-line arguments and Agent-readable content.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_image.sh:232
Finding

Unrestricted Fetching of API-Provided URLs Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.sh:232-245
Vulnerability Type: Server-side request forgery through unvalidated response URLs
Risk Level: High

Vulnerable Code

sh
case "$url" in
  data:*base64,*)
    data="${url#*,}"
    printf '%s' "$data" | base64 -d > "$target_path"
    ;;
  data:*)
    data="${url#*,}"
    printf '%b' "$(printf '%s' "$data" | sed 's/%/\\x/g')" > "$target_path"
    ;;
  *)
    curl -sS -o "$target_path" "$url"
    ;;
esac

Technical Analysis

Image URLs extracted from the remote API response are passed directly to curl without scheme, hostname, port, DNS result, or destination validation. The code assumes that every non-data URL in the response is a safe image location.

A malicious or compromised API endpoint can return a URL targeting loopback services, private network systems, link-local addresses, cloud metadata services, or other protocols supported by the installed curl build. The response is then written into the Skill's output directory.

This risk is amplified by the separately configurable and insufficiently validated OPENROUTER_BASE_URL, but exploitation is also possible if the legitimate upstream service or its response path is compromised.

Attack Path

  1. An attacker controls or compromises the configured API endpoint.
  2. The endpoint returns a syntactically valid response containing an image_url such as a loopback, private-network, or cloud metadata address.
  3. The script extracts the attacker-provided URL.
  4. The wildcard branch invokes curl against that URL.
  5. The host running the Skill makes the request from its own network context.
  6. The fetched response is stored as a local output file.
  7. Depending on access to generated media or output paths, sensitive internal response data may be disclosed.

Impact Assessment

An attacker may cause requests to services reachable from the Skil ...[truncated 371 chars]

Remediation
View remediation

Remediation Suggestions

  • Permit only https:// image URLs.
  • Invoke curl with a protocol restriction such as --proto '=https'.
  • Allowlist trusted image-delivery hostnames.
  • Resolve destinations and reject loopback, link-local, private, multicast, unspecified, and reserved address ranges for both IPv4 and IPv6.
  • Revalidate every redirect destination or disable redirects entirely.
  • Set conservative connection, transfer, and file-size limits.
  • Validate the response content type and image signature before publishing the file.
  • Prefer image data returned directly by the trusted API rather than arbitrary secondary URLs.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.sh:164
Finding

Predictable Output Files Can Be Redirected Through Symbolic Links

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.sh:164-168, 222-244
Vulnerability Type: Symbolic-link file overwrite
Risk Level: Medium

Vulnerable Code

sh
output_base_dir="$HOME/.openclaw/workspace/outputs/nano-banana-pro-openrouter"
mkdir -p "$output_base_dir"
output_name=$(basename "$filename")
output_path="$output_base_dir/$output_name"
sh
if [ "$index" -eq 1 ]; then
  target_path="$output_path"
else
  base="${output_path%.*}"
  ext="${output_path##*.}"
  if [ "$base" = "$output_path" ]; then
    target_path="${output_path}-$index"
  else
    target_path="${base}-$index.${ext}"
  fi
fi

case "$url" in
  data:*base64,*)
    data="${url#*,}"
    printf '%s' "$data" | base64 -d > "$target_path"
    ;;
  data:*)
    data="${url#*,}"
    printf '%b' "$(printf '%s' "$data" | sed 's/%/\\x/g')" > "$target_path"
    ;;
  *)
    curl -sS -o "$target_path" "$url"
    ;;
esac

Technical Analysis

Applying basename prevents direct path traversal through --filename, but it does not prevent symbolic-link attacks. The script writes directly to a predictable path and does not reject pre-existing files, verify that the destination is a regular file, or use no-follow and exclusive-creation semantics.

If another local process or user can create entries in the output directory, that party can place a symbolic link at the expected output path. Shell redirection and curl -o will follow the link and overwrite its target with image or response data.

Timestamped automatic filenames reduce predictability but do not eliminate the race condition, particularly when a caller supplies a known filename.

Attack Path

  1. An attacker obtains write access to the output directory or can create a file at the selected output name.
  2. The attacker predicts or observes the filename that will be used.
  3. The attacker creates a symbolic link from tha ...[truncated 738 chars]
Remediation
View remediation

Remediation Suggestions

  • Ensure the output directory is owned by the Skill user and not writable by other users.
  • Set a restrictive umask, such as 077, before creating output files.
  • Reject destinations that already exist, including symbolic links.
  • Create temporary files atomically with exclusive permissions inside the trusted output directory.
  • Use no-follow file creation semantics through a suitable helper or safer implementation language.
  • Validate the destination with lstat and atomically rename the completed temporary file into place.
  • Avoid overwriting an existing filename unless the user explicitly requests replacement and the existing object is verified as a regular file.
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
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
Findings (19)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

By instructing behavior around .env file loading in the working directory and skill directory, the skill encourages credential discovery from local files. In the context of an agent, this is sensitive because .env files often contain unrelated secrets beyond the API key needed for this task.

Content

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

md
The API base URL must be set via OPENROUTER_BASE_URL. Use the full chat
completions endpoint (for OpenRouter: `https://openrouter.ai/api/v1/chat/completions`).

The script also loads .env files automatically (if present):
- Current working directory .env
- Skill directory .env

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The documented auto-loading of .env files increases the chance that credentials are sourced from local storage without explicit user awareness. This broadens the attack surface by making secret retrieval part of the normal workflow.

Content

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

md
completions endpoint (for OpenRouter: `https://openrouter.ai/api/v1/chat/completions`).

The script also loads .env files automatically (if present):
- Current working directory .env
- Skill directory .env

Important: If a .env file exists, do not ask the user for the key up front.

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

Telling the agent not to ask the user if a .env file exists reinforces silent credential consumption from local files. In a skill that also sends data to an external API, this materially increases the risk of unauthorized secret use and accidental exposure.

Content

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

md
The script also loads .env files automatically (if present):
- Current working directory .env
- Skill directory .env

Important: If a .env file exists, do not ask the user for the key up front.
Just run the script and only ask if it errors with "No API key provided."

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

This instruction operationalizes secret use without user interaction when a .env file is present. Combined with shell execution and external API calls, it creates an unsafe pattern where the agent is encouraged to discover and use local secrets autonomously.

Content

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

md
- Current working directory .env
- Skill directory .env

Important: If a .env file exists, do not ask the user for the key up front.
Just run the script and only ask if it errors with "No API key provided."

### OpenClaw Chat Execution Rules

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The skill specifically directs the agent to read a concrete .env path under the workspace. This is a direct credential-access pattern and is especially risky because it turns secret file inspection into an expected execution step rather than an exceptional admin task.

Content

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

md
### OpenClaw Chat Execution Rules

- OpenClaw does NOT auto-source the skill .env file
- If `~/.openclaw/workspace/skills/nano-banana-pro-openrouter/.env` exists:
  1. Use the `read` tool to read `.env`
  2. Extract `OPENROUTER_API_KEY` and `OPENROUTER_BASE_URL`

Ssd 3

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The skill explicitly instructs the agent to read secrets from a .env file, extract the API key, and pass it on the command line. This is dangerous because it causes direct secret handling by the agent and may expose credentials through logs, process listings, transcripts, or downstream tooling.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
99% confidence
Finding

The agent is told to always pass the extracted API key via --api-key after reading .env. Passing secrets on the command line can expose them through process arguments, audit logs, shell history, or telemetry, compounding the credential-access risk.

Content

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

md
1. Use the `read` tool to read `.env`
  2. Extract `OPENROUTER_API_KEY` and `OPENROUTER_BASE_URL`
  3. Always pass the key via `--api-key` when running the script
- Only ask the user if .env is missing or the key cannot be read
- If the user asks for a timestamped filename, prefer `--filename auto` (do not handwrite dates)

If neither is available, the script exits with an error message.

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

The troubleshooting guidance explicitly tells the agent to read .env and retry with --api-key on failure. This bakes credential retrieval and insecure secret transmission into error handling, making the unsafe path more likely during normal use.

Content

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

md
- `command -v base64` (must exist)

Common failures:
- `Error: No API key provided.` -> read .env and retry with --api-key; if still failing, ask the user to set OPENROUTER_API_KEY
- `Error: No API base URL provided.` -> ensure OPENROUTER_BASE_URL is set to a full chat completions endpoint
- `Error loading input image:` -> wrong path or unreadable file; verify --input-image points to a real image
- "quota/permission/403" style API errors -> wrong key, no access, or quota exceeded; try a different key/account

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

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

md
- Prompt "A serene Japanese garden" -> `2025-11-23-14-23-05-japanese-garden.png`
- Prompt "sunset over mountains" -> `2025-11-23-15-30-12-sunset-mountains.png`
- Prompt "create an image of a robot" -> `2025-11-23-16-45-33-robot.png`
- Unclear context -> `2025-11-23-17-12-48-image.png`

Tip: To avoid incorrect timestamps, pass `--filename auto` and let the script
generate the filename using the system clock.

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/generate_image.sh (reported line 142)May include surrounding context.

sh
script_dir=$(cd "$(dirname "$0")" && pwd)
skill_dir=$(cd "$script_dir/.." && pwd)

load_env_file "$PWD/.env"
load_env_file "$skill_dir/.env"

if [ -z "$api_key" ]; then

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/generate_image.sh (reported line 143)May include surrounding context.

sh
script_dir=$(cd "$(dirname "$0")" && pwd)
skill_dir=$(cd "$script_dir/.." && pwd)

load_env_file "$PWD/.env"
load_env_file "$skill_dir/.env"

if [ -z "$api_key" ]; then

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill invokes shell commands but does not declare a restrictive tool scope such as allowed-tools or permissions. That increases the chance the agent can use shell more broadly than intended, which weakens sandboxing and review controls for a networked, file-accessing skill.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The invocation criteria are broad enough to trigger on generic image-generation requests, which can cause the agent to route more conversations than necessary into a shell-based external API workflow. Over-broad activation increases unnecessary exposure of prompts, files, and credentials to this skill's execution path.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

At L018 the file says the shell version supports generation only and no input image editing. However, later lines reference '--input-image' failures and discuss image editing support, which actively conflicts with the earlier limitation and could cause the agent to attempt unsupported behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill does not clearly disclose that user prompts and related metadata will be sent to OpenRouter, a third-party external service. This undermines informed consent and can lead to unintended disclosure of sensitive or proprietary user content.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation tells the agent to read local .env files and extract credentials, which expands the skill from image generation into secret discovery and handling. Even if intended for convenience, instructing an agent to inspect local secret stores creates an unnecessary credential exposure path and normalizes secret harvesting behavior.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
- Current working directory .env
- Skill directory .env

Important: If a .env file exists, do not ask the user for the key up front.
Just run the script and only ask if it errors with "No API key provided."

### OpenClaw Chat Execution Rules

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

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

md
2. Extract `OPENROUTER_API_KEY` and `OPENROUTER_BASE_URL`
  3. Always pass the key via `--api-key` when running the script
- Only ask the user if .env is missing or the key cannot be read
- If the user asks for a timestamped filename, prefer `--filename auto` (do not handwrite dates)

If neither is available, the script exits with an error message.

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/generate_image.sh (reported line 197)May include surrounding context.

sh
response_file=$(mktemp)
trap 'rm -f "$response_file"' EXIT

if ! http_code=$(curl -sS -o "$response_file" -w "%{http_code}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $api_key" \
  -d "$payload" \

Static analysis

No suspicious patterns detected.