Back to skill

Security audit

Nano Banana Pro via cheaper grsai.com

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it sends prompts/images to a third-party API and unsafely downloads whatever result URL that service returns.

Review before installing. Use it only if you are comfortable sending prompts and any edited images to the grsai API, prefer a protected GRSAI_API_KEY over chat or command-line keys, and avoid running it in environments with sensitive internal network access unless URL validation and download limits are added.

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_image.py:250
Finding

Unvalidated Provider-Controlled URL Enables SSRF and Arbitrary Resource Retrieval

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.py, lines 250–259
Vulnerability Type: Server-Side Request Forgery (SSRF) and unrestricted URL scheme handling
Risk Level: Medium

Vulnerable Code:

python
image_url = result["results"][0]["url"]
content = result["results"][0].get("content", "")
if content:
    print(f"Model response: {content}")

print("Downloading image...")
try:
    with urllib.request.urlopen(image_url, timeout=60 * 2) as resp:
        output_path.write_bytes(resp.read())
except Exception as e:

Technical Analysis

The image URL returned by the remote generation provider is passed directly to urllib.request.urlopen() without validation. The code does not restrict the URL scheme, allowlist trusted CDN hostnames, reject private or reserved IP addresses, validate redirect destinations, limit response size, or verify that the response is an image.

Because urlopen() supports multiple URL schemes and automatically follows HTTP redirects, a compromised or malicious API response could direct the process to:

  • Loopback services such as 127.0.0.1.
  • Private network services accessible from the host.
  • Link-local cloud metadata endpoints.
  • Unexpected local or remote resources supported by the URL handler.
  • An initially trusted URL that redirects to a prohibited destination.

The provider-controlled response body is then written to the user-selected output path without content validation. Although the retrieved content is not subsequently transmitted elsewhere by this script, the behavior creates an SSRF primitive and may expose local or internal content in the output file.

Attack Path

  1. A user invokes the Skill to generate or edit an image.
  2. The script submits the prompt and optional input image to grsaiapi.com.
  3. The provider account, API infrastructure, or returned task data is compromised or manipulated.
  4. The task result supplies ...[truncated 1058 chars]
Remediation
View remediation

Remediation Suggestions

  • Accept only https result URLs.
  • Maintain an explicit allowlist of expected image CDN hostnames.
  • Resolve the destination hostname and reject loopback, private, link-local, multicast, unspecified, and reserved addresses for both IPv4 and IPv6.
  • Disable automatic redirects or validate the scheme, hostname, port, and resolved addresses of every redirect destination.
  • Enforce a maximum response size using both Content-Length and bounded streaming reads.
  • Require an expected image Content-Type.
  • Decode and validate the downloaded file as a supported image before committing it to the final output path.
  • Download to a securely created temporary file and atomically rename it after successful validation.
  • Consider having the trusted API return image bytes through an authenticated endpoint rather than accepting arbitrary result URLs.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/generate_image.py:153
Finding

API Key Exposure Through Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_image.py, line 153
Vulnerability Type: Sensitive credential exposure through process arguments
Risk Level: Low

Vulnerable Code:

python
parser.add_argument("--api-key", "-k", help="grsai API key (overrides GRSAI_API_KEY env var)")

The accompanying SKILL.md documentation also recommends the following invocation pattern:

bash
uv run ~/.codex/skills/nano-banana-pro/scripts/generate_image.py \
  --prompt "your image description" \
  --filename "output-name.png" \
  --api-key KEY

Technical Analysis

Supplying credentials through command-line arguments can expose them through shell history, process listings, execution telemetry, audit logs, terminal recordings, and wrapper-tool diagnostics. The documentation also permits using a key supplied in chat, which unnecessarily places the credential in conversation records before it reaches the command line.

Supporting the GRSAI_API_KEY environment variable is safer than exposing the key as an argument, although protected credential injection or a secret manager would provide stronger isolation.

Attack Path

  1. A user follows the documented workflow and includes the API key in the --api-key argument.
  2. The complete command is retained in shell history, Agent execution logs, or terminal telemetry, or is visible in the process argument list while the program runs.
  3. Another local user, process-monitoring component, log reader, or person with access to conversation history obtains the credential.
  4. The exposed key is used to make unauthorized requests to the image-generation service until the key is revoked or expires.

Impact Assessment

Exposure grants the attacker the API permissions associated with the compromised key. This may permit unauthorized image-generation requests, account quota consumption, billing impact, and access to any provider-side operations author ...[truncated 233 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove the --api-key option or mark it as deprecated and unsafe.
  • Prefer a protected credential store, runtime secret injection, or the existing GRSAI_API_KEY environment variable.
  • If interactive use is required, obtain the key through a hidden prompt such as getpass.getpass() rather than command-line arguments.
  • Update SKILL.md so it does not instruct users to provide secrets in chat or place them directly on the command line.
  • Ensure application logs never print authorization headers or credential values.
  • Recommend immediate rotation if a key has already been shared through chat, logs, or shell history.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (5)

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 89)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

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs use of a script that accesses environment variables, reads and writes files, and makes network requests, but the manifest does not declare any tool scope or permissions. That creates a transparency and policy-enforcement gap: users and hosting systems cannot clearly assess or constrain what the skill is allowed to do before execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill sends user prompts and, for edits, local input images to the external grsai.com API, but the description and usage text do not prominently warn the user about this data transfer. This can lead to unintentional disclosure of sensitive text, proprietary images, or personal data to a third-party service.

Content

No source excerpt is available for this finding.

Indirect Prompt Extraction

Medium
Category
System Prompt Leakage
Confidence
75% confidence
Finding

Skill contains patterns that could indirectly extract system prompts through rephrasing, translation, summarization, or side-channel techniques.

Content

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

md
- `Error: No API key provided.` → set `GRSAI_API_KEY` or pass `--api-key`
  - `Error loading input image:` → wrong path / unreadable file
  - HTTP 401 → wrong or expired API key
  - `Generation failed:` → content moderation or invalid input; rephrase prompt

## Filename Generation

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 88)May include surrounding context.

md
Examples:
- 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