Back to skill

Security audit

nano-banana-pro-openrouter

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a real OpenRouter image generator, but it needs review because it handles API keys and can write generated files to overly broad local paths.

Install only if you are comfortable sending prompts and any input images to OpenRouter. Prefer setting OPENROUTER_KEY in the environment instead of providing keys in chat or command arguments, and use simple output filenames in the skill's own output_images directory to avoid accidental overwrites.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_and_return.py:63
Finding

OpenRouter API Key Exposure Through Command-Line Arguments

Content
View full analysis
/cmdline`. - Shell history. - Agent execution logs and telemetry. - Process-monitoring and debugging tools. - Error reports that record the invoked command. This behavior is not required for the declared image-generation functionality because the implementation already supports obtaining the credential from the `OPENROUTER_KEY` environment variable. No evidence indicates that the key is intentionally transmitted anywhere except the documented OpenRouter endpoint. The vulnerability is the unnecessary local exposure of the credential before that legitimate transmission. ### Attack Path 1. A user or Agent invokes the Skill with `--api-key `, as supported by the documentation. 2. `generate_and_return.py` places the plaintext key in the child process argument list. 3. A local user, process monitor, execution logger, or telemetry service records or ...[truncated 789 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:121
Finding

Unrestricted Output Path Allows Overwriting Arbitrary Writable Files

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (7)

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 94)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-x9k2.png`

## Image Editing

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/generate_image.py (reported line 24)May include surrounding context.

python
from typing import Any

def get_api_key(provided_key: str | None) -> str | None:
    """Get API key from argument first, then environment."""
    if provided_key:
        return provided_key
    return os.environ.get("OPENROUTER_KEY")

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documents use of shell execution, environment variables, and outbound network access, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an authorization gap where an agent may invoke broader capabilities than users expect, increasing the chance of unintended command execution, secret exposure from environment variables, or unsanctioned external requests.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill sends user prompts and potentially input images to the external OpenRouter service, but the documentation does not warn users that their data leaves the local environment. This can cause inadvertent disclosure of sensitive text, proprietary content, or private images to a third party, especially in image-editing workflows.

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 · scripts/generate_and_return.py (reported line 96)May include surrounding context.

python
# Run generation
    try:
        result = subprocess.run(
            cmd,
            cwd=str(skill_dir),
            capture_output=True,

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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.py (reported line 62)May include surrounding context.

python
"Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    }
    resp = requests.post(url, headers=headers, json=payload, timeout=180)
    if not resp.ok:
        raise RuntimeError(f"OpenRouter API error: HTTP {resp.status_code}: {resp.text}")
    return resp.json()

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

L124 says outputs are saved to the current directory or a path embedded in the filename, but earlier documentation states the default output location is ./output_images/ and that --output-dir controls custom output placement. This is an active contradiction in the skill's own documentation about a user-visible side effect.

Content

No source excerpt is available for this finding.