Back to skill

Security audit

Bananapro Image Gen

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent image-generation helper, but it under-discloses that prompts, input images, and API keys may be sent through a recommended third-party relay or arbitrary configured endpoint.

Install only if you are comfortable sending your prompts, selected source images, and API credentials to the configured endpoint. Prefer the official Gemini endpoint, avoid unknown relays, use a separate revocable API key, do not put sensitive images into --input-image, and consider pinning dependencies before 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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_image.py:53
Finding
API Credential Embedded in Request URL## Vulnerability Details **File Location**: `scripts/generate_image.py`, lines 53–57 **Vulnerability Type**: API credential exposure through a URL query parameter **Risk Level**: Medium **Vulnerable Code**: ```python if not api_url: api_url = os.environ.get("NEXTAI_API_URL", "https://generativelanguage.googleapis.com/v1beta") # Construct the request URL url = f"{api_url.rstrip('/')}/models/{model}:generateContent?key={api_key}" ``` ### Technical Analysis The API key is appended directly to the request URL as the `key` query parameter. URLs are commonly captured by reverse-proxy access logs, API gateway logs, monitoring systems, debugging tools, and server-side request telemetry. Consequently, a secret placed in the query string can persist in systems that would not normally record authorization headers. The destination is configurable through `NEXTAI_API_URL` or `--api-url`. If a user selects a third-party or attacker-controlled endpoint, the endpoint receives the complete request URL and therefore the API key. HTTPS protects the request in transit but does not protect the credential from the destination server or its logs. No key is hardcoded in the repository, and the script does not print the URL. Nevertheless, transmitting a secret in the URL unnecessarily expands its exposure. ### Attack Path 1. A user configures `NEXTAI_API_URL` or supplies `--api-url`, potentially following third-party relay guidance. 2. The script obtains the API key from an argument or environment variable. 3. The script appends the key to the generated request URL. 4. The destination server, reverse proxy, gateway, or monitoring system records the URL. 5. An operator or attacker with access to those logs extracts the API key. 6. The exposed key is used to issue unauthorized API requests until it is revoked or expires. ### Impact Assessment Exploitation can disclose the configured API credential. An attacker could consume the ...[truncated 387 chars]
Remediation
## Remediation Suggestions - Prefer an authorization header supported by the selected API, such as `Authorization: Bearer ...` or the provider-specific API-key header, instead of a query parameter. - Separate official Gemini authentication from OpenAI-compatible relay authentication rather than applying one URL construction method to every endpoint. - Permit only HTTPS endpoints and reject cleartext HTTP URLs. - Warn users before transmitting credentials to a host other than an explicitly trusted official endpoint. - Redact query parameters and authorization values from exceptions, diagnostics, proxy logs, and application telemetry. - Use separate, narrowly scoped credentials for third-party relays and rotate any credential that may have appeared in logs.

other

Warning
Location
SKILL.md:32
Finding
Recommended Third-Party Relay Receives Sensitive User Content and Credentials## Vulnerability Details **File Location**: `SKILL.md`, lines 32–47 **Vulnerability Type**: Undisclosed third-party trust boundary and sensitive-data exposure **Risk Level**: Medium **Relevant Configuration Snippet**: ```text apipro.maynor1024.live https://apipro.maynor1024.live/ export NEXTAI_API_KEY="your-api-key" ``` ### Technical Analysis The documentation recommends a third-party API relay and directs users to register with it and configure a relay credential. Image generation necessarily transmits prompts to the selected API. The documented image-editing feature additionally Base64-encodes the user-selected source image and places it in the request payload. Base64 is a transport encoding rather than encryption or concealment. The upload behavior is consistent with the declared image-editing functionality and is not evidence of covert exfiltration. However, when a third-party relay is selected, that relay can inspect, retain, or process the prompt, source image, request metadata, and credential used to authenticate the request. The documentation provides only a general statement that selecting a trustworthy relay is important. It does not establish the relay's provenance, retention policy, privacy guarantees, or security controls. Recommending the relay as the preferred option exposes data beyond the official provider even though the implementation supports an official endpoint. There is also a documentation inconsistency: the documentation describes the relay as the default or recommended service, while `scripts/generate_image.py` actually defaults to Google's official endpoint unless `NEXTAI_API_URL` or `--api-url` is supplied. ### Attack Path 1. A user follows the recommended relay setup and obtains or configures a relay API key. 2. The user submits a private prompt or invokes image editing with a sensitive local image. 3. The script reads the explicitly selected image and Base64-encodes its entire contents. ...[truncated 956 chars]
Remediation
## Remediation Suggestions - Make the official Gemini endpoint the clearly documented default and preferred option. - Require explicit user opt-in before sending prompts or images to a third-party relay. - Display the final destination hostname before transmitting an input image. - Clearly disclose that the destination can read prompts, source images, credentials, and metadata. - Document the relay operator, privacy policy, data-retention policy, security controls, and incident-response process before recommending it. - Consider allowlisting reviewed endpoint hostnames or requiring interactive confirmation for unknown hosts. - Encourage users to employ relay-specific, revocable, least-privilege credentials rather than reusing official provider credentials. - Reconcile `SKILL.md` with the implementation so that the documented default endpoint is accurate.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding
Unpinned Dependency Allows Unreviewed Future Releases## Vulnerability Details **File Location**: `requirements.txt`, line 1 **Vulnerability Type**: Non-reproducible dependency resolution **Risk Level**: Low **Vulnerable Code**: ```text requests>=2.28.0 ``` ### Technical Analysis The dependency specifies only a minimum version. A future installation can therefore resolve to any later `requests` release accepted by the package resolver. The repository provides neither an exact version lock nor package hashes, so installations performed at different times may execute different dependency code despite using the same project revision. No evidence indicates that the named `requests` package is malicious or misspelled. The risk is that future, compromised, or behaviorally incompatible releases remain eligible without additional review. The README further suggests installing the package without a version constraint, which has the same reproducibility weakness. ### Attack Path 1. A future dependency release satisfying `requests>=2.28.0` becomes compromised or introduces a security regression. 2. A user installs the project dependencies after that release is available. 3. The package resolver selects the affected release because no upper bound, exact pin, lock file, or hash prevents it. 4. The affected package code is imported when `generate_image.py` runs. 5. Malicious or vulnerable dependency behavior executes with the privileges of the user running the Skill. ### Impact Assessment A compromised dependency could execute Python code with the same operating-system permissions as the Skill process. Depending on the dependency behavior, this could expose API credentials, prompts, images, local files accessible to the user, or network access available to the process. This is a supply-chain hardening weakness rather than evidence of an existing malicious dependency. The practical risk is therefore lower than a confirmed compromised package.
Remediation
## Remediation Suggestions - Pin `requests` and its transitive dependencies to reviewed versions through a lock file. - Generate and verify cryptographic hashes, such as by installing with `pip --require-hashes`. - Update the README installation command to use the audited requirements or lock file rather than unconstrained `pip install requests`. - Review dependency updates before regenerating the lock file. - Use automated dependency vulnerability scanning and controlled update tooling. - Install dependencies in an isolated virtual environment under a non-privileged account.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (10)

Tainted flow: 'url' from os.environ.get (line 56, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
# 发送请求
    try:
        response = requests.post(
            url,
            headers={"Content-Type": "application/json"},
            json=payload,
Confidence
94% confidence
Finding
The request destination is derived from an environment-controlled API base URL and can be overridden to any host, while the API key is embedded in the query string. In a skill context, this creates a realistic credential exfiltration path: a manipulated NEXTAI_API_URL can cause prompts, optional input images, and the API key to be sent to an attacker-controlled endpoint.

Natural-Language Policy Violations

Medium
Confidence
90% confidence
Finding
The README presents the skill instructions and examples entirely in Chinese, which effectively forces a specific language for users without opt-in. The policy calls for flagging language or locale constraints unless the skill offers a choice or clearly documents a justified regional limitation.

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill documents behavior that relies on environment variables and outbound network access, but it does not declare any tool scope or permissions. This weakens reviewability and least-privilege controls, because users and platforms cannot clearly see that the skill may read API keys from the environment and transmit data externally.

Missing User Warnings

Medium
Confidence
97% confidence
Finding
The documentation recommends a third-party proxy API and presents it as the default/recommended path without a clear warning that prompts, images, and API credentials will transit a non-official service. In this skill's context, users may upload or edit images and provide sensitive prompts, so routing both content and secrets through an untrusted intermediary materially increases the risk of credential theft, logging, retention, or misuse of user data.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The file’s natural-language description is written as a Chinese-only instruction ('使用 Gemini 图像模型生成图片'), and all user-facing messages and CLI help text are likewise Chinese-only. This imposes a specific language/locale on users without offering a choice or documenting why the skill must be Chinese-specific.

External Transmission

Medium
Category
Data Exfiltration
Content
# 发送请求
    try:
        response = requests.post(
            url,
            headers={"Content-Type": "application/json"},
            json=payload,
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
84% confidence
Finding
This markdown file includes setup steps for storing a credential in an environment variable, but it does not warn users that the value is sensitive or should be protected. Under the markdown-specific warning criteria, omission of privacy or credential-handling cautions can leave users unaware of security implications.

Natural-Language Policy Violations

Low
Confidence
85% confidence
Finding
The natural-language content and usage instructions are predominantly in Chinese, and the skill does not indicate that the language is optional or that users can choose another locale. Under the language/locale policy, forcing a specific language without user opt-in can be a policy concern unless the locale limitation is clearly documented and justified.

Unpinned Dependencies

Low
Category
Supply Chain
Content
requests>=2.28.0
Confidence
93% confidence
Finding
The dependency is specified as `requests>=2.28.0`, which allows uncontrolled upgrades to any newer release and prevents reproducible installs. This increases supply-chain risk and can unexpectedly introduce vulnerable or breaking versions into the skill at install time.

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding
Because `requests` is not pinned, it is not possible to verify whether the installed version avoids known advisories affecting some `requests` releases. In practice, this means deployments may resolve to a version with a disclosed vulnerability, especially across different environments or future installs.

Static analysis

No suspicious patterns detected.