Back to skill

Security audit

nano banana 2

Security checks for vulnerabilities and agentic risk

Overview

The skill appears to be a normal Google image-generation helper, but its documentation points to a different skill path and handles sensitive prompts, images, and API keys with weak disclosure.

Review this before installing. Use only the inspected script path, avoid sending private or regulated images/prompts unless Google processing is acceptable, set GEMINI_API_KEY through a protected environment variable rather than chat or --api-key, and consider pinning dependencies before routine use.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T08 · Insecure Dependencies

Warning
Location
scripts/generate_image.py:3
Finding
Unpinned Runtime Dependencies Permit Unreviewed Package Updates<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:3-7` **Vulnerability Type**: Supply-chain risk caused by open-ended dependency constraints **Risk Level**: Medium ### Vulnerable Code ```python # /// script # requires-python = ">=3.10" # dependencies = [ # "google-genai>=1.0.0", # "pillow>=10.0.0", # ] # /// ``` ### Technical Analysis The script declares its runtime dependencies using minimum-version constraints without exact versions, upper bounds, package hashes, or a committed lockfile. The documented execution workflow uses `uv run`, which can resolve and install a future package release that satisfies these constraints. Consequently, the code reviewed during this audit is not sufficient to determine the exact third-party code that will execute in future invocations. A compromised package release, malicious maintainer update, or unexpected incompatible release of `google-genai` or `pillow` could be installed without a separate review. This finding does not establish that the currently available packages are malicious. It identifies an unsafe dependency-resolution practice that creates a supply-chain exploitation path. ### Attack Path 1. An attacker compromises the publication process, maintainer account, or distribution channel of a permitted dependency. 2. The attacker publishes a malicious version whose version number satisfies `google-genai>=1.0.0` or `pillow>=10.0.0`. 3. A user invokes the documented `uv run` command in an environment that has not locked the dependency to a previously reviewed version. 4. The dependency resolver downloads and installs the malicious release. 5. Package code executes in the Python process with the operating-system permissions of the user running the skill. ### Impact Assessment Successful exploitation could provide arbitrary code execution under the invoking user's account. Depending on that account's permissions, an attacker could access local files, environment variables ...[truncated 261 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace minimum-version constraints with exact, reviewed versions, for example: ```python # dependencies = [ # "google-genai==<reviewed-version>", # "pillow==<reviewed-version>", # ] ``` 2. Generate and commit a lockfile that records all direct and transitive dependency versions. 3. Use package hash verification where supported to ensure downloaded artifacts match approved files. 4. Perform dependency upgrades through a controlled review process rather than resolving unrestricted future releases at runtime. 5. Run dependency vulnerability and provenance checks in CI before accepting lockfile updates. 6. Prefer an isolated environment with only the filesystem and network permissions required for image generation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:87
Finding
Gemini API Key Can Be Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_image.py:87-101` **Vulnerability Type**: Sensitive credential exposure through process arguments and command history **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument( "--api-key", "-k", help="Gemini API key (overrides GEMINI_API_KEY env var)" ) args = parser.parse_args() # Get API key api_key = get_api_key(args.api_key) if not api_key: print("Error: No API key provided.", file=sys.stderr) print("Please either:", file=sys.stderr) print(" 1. Provide --api-key argument", file=sys.stderr) print(" 2. Set GEMINI_API_KEY environment variable", file=sys.stderr) sys.exit(1) ``` The associated documentation also explicitly recommends this mechanism in `SKILL.md:147-152`: ```markdown ## API Key The script checks for API key in this order: 1. `--api-key` argument (use if user provided key in chat) 2. `GEMINI_API_KEY` environment variable If neither is available, the script exits with an error message. ``` ### Technical Analysis Secrets supplied as command-line arguments can be retained in shell history, terminal-session logs, automation logs, and process-launch telemetry. On systems where process arguments are visible to other local users or monitoring software, the key may also be observable while the process is running. The documentation compounds this risk by suggesting that users may provide an API key through chat. Chat transcripts can be retained, synchronized, logged, or accessed by additional participants and systems. The script does not print the key directly, but accepting and recommending a plaintext command-line credential creates avoidable exposure outside the script's internal processing. ### Attack Path 1. A user provides a Gemini API key in chat or invokes the script with `--api-key <secret>`. 2. The complete command is retained in shell history, execution logs, terminal capture, agent transcripts, or process metadata. ...[truncated 859 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--api-key` command-line option, or clearly deprecate it and reject its use by default. 2. Prefer a protected environment variable, operating-system credential store, or configuration file restricted to the owning user. 3. Do not instruct users to send API keys through chat or include them in prompts, transcripts, issue reports, or command examples. 4. If interactive credential entry is necessary, use a non-echoing prompt such as Python's `getpass.getpass()` and avoid persisting the value. 5. Ensure CI and automation systems inject the key through their native secret-management facilities with log masking enabled. 6. Document immediate key revocation and rotation procedures for credentials previously supplied through command lines or chat. 7. Apply the narrowest available API permissions, quotas, and billing limits to reduce the impact of credential compromise. ]]>
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (12)

Missing User Warnings

High
Confidence
98% confidence
Finding
The skill lacks a clear warning that prompts and input images are transmitted to Google's external API. Users may unknowingly send sensitive content off-device, creating privacy, confidentiality, and compliance risks in contexts involving personal, proprietary, or regulated data.

Memory Manipulation

High
Category
Memory Poisoning
Content
- 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
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Credential Access

High
Category
Privilege Escalation
Content
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("GEMINI_API_KEY")
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill instructs use of environment-provided secrets (`GEMINI_API_KEY`) and external command execution, but the manifest declares no explicit tool scope or permissions boundary. This can cause the agent to invoke the skill with broader capabilities than the user realizes, especially around environment access and outbound API use.

Vague Triggers

Medium
Confidence
89% confidence
Finding
The description says to use the skill broadly for image create/modify requests, which can cause the agent to route sensitive editing tasks through an external provider by default. Overbroad invocation guidance increases the chance of unintended disclosure of private images, copyrighted material, or confidential prompts.

Session Persistence

Medium
Category
Rogue Agent
Content
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
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.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The documentation says the skill uses the Google Nano Banana 2 API, but it does not clearly warn that user prompts and any supplied images are transmitted to an external third-party service. This creates a privacy and data-handling risk because users may provide sensitive images, proprietary content, or confidential prompts without informed consent.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The skill manifest identifies this skill as "nano-banana-2", but the usage examples instruct execution of a different path, `~/.codex/skills/nano-banana-pro/scripts/generate_image.py`. This mismatch can cause the agent or user to invoke the wrong skill implementation, potentially bypassing the reviewed artifact and running a different script with different security properties.

Session Persistence

Medium
Category
Rogue Agent
Content
当用户描述模糊或编辑需要精确时使用模板。

- 生成模板:
  - "Create an image of: <主题>. Style: <风格>. Composition: <构图/镜头>. Lighting: <光线>. Background: <背景>. Color palette: <色调>. Avoid: <排除项>."

- 编辑模板(保留其他所有内容):
  - "Change ONLY: <单一修改>. Keep identical: subject, composition/crop, pose, lighting, color palette, background, text, and overall style. Do not add new objects. If text exists, keep it unchanged."
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.

Session Persistence

Medium
Category
Rogue Agent
Content
当用户描述模糊或编辑需要精确时使用模板。

- 生成模板:
  - "Create an image of: <主题>. Style: <风格>. Composition: <构图/镜头>. Lighting: <光线>. Background: <背景>. Color palette: <色调>. Avoid: <排除项>."

- 编辑模板(保留其他所有内容):
  - "Change ONLY: <单一修改>. Keep identical: subject, composition/crop, pose, lighting, color palette, background, text, and overall style. Do not add new objects. If text exists, keep it unchanged."
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.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The file is primarily written in English, but the model table switches to Chinese column headers and feature descriptions with no user opt-in or explanation. This creates a language-policy inconsistency by imposing a different locale on part of the skill documentation.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
文件整体以中文编写并面向操作指令,但未说明这是可选语言版本,也未给出用户语言选择。按照语言/区域政策,若技能实际上强制特定语言而没有用户 opt-in,属于自然语言策略风险。

Static analysis

No suspicious patterns detected.