Back to skill

Security audit

banana

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent image-generation client, but it should be reviewed because it encourages unsafe API-key handling and sends credentials and user content over plain HTTP.

Review this skill before installing. Use it only if you trust the NewAPI Banana provider and can configure the API key outside chat. Do not paste API keys into conversations, prefer a protected secret store or tightly permissioned config, avoid command-line API keys, and rotate any key already used with the documented HTTP endpoint or shared in chat. The publisher should switch to HTTPS-only API URLs, reject arbitrary authenticated hosts, and validate downloaded image URLs and file contents.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/newapi-banana.py:24
Finding

API Credentials and User Content Are Transmitted Over Plaintext HTTP

Content
View full analysis

Vulnerability Details

File Location: scripts/newapi-banana.py:24, scripts/newapi-banana.py:133-159, scripts/newapi-banana.py:260-290, scripts/newapi-banana.py:322-346; also documented in SKILL.md:7,104-105 and install.md:53-59,94-95
Vulnerability Type: Plaintext transmission of sensitive information
Risk Level: High

Vulnerable Code

python
# API host
DEFAULT_HOST = "http://nen.baynn.com"
python
def curl_post_json(url: str, payload: dict, headers: dict, timeout: int = 60) -> subprocess.CompletedProcess:
    with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
        json.dump(payload, f)
        tmp_path = f.name
    try:
        cmd = ["curl", "-s", "-S", "--fail-with-body", "-X", "POST", url,
               "--max-time", str(timeout), "-d", f"@{tmp_path}"]
        for k, v in headers.items():
            cmd += ["-H", f"{k}: {v}"]
        return subprocess.run(cmd, capture_output=True, text=True)
    finally:
        os.unlink(tmp_path)
python
if args.image:
    image_path = Path(args.image)
    if not image_path.exists():
        print(f"Error: image file not found: {args.image}", file=sys.stderr)
        sys.exit(1)
    mime_type = mimetypes.guess_type(str(image_path))[0] or "image/png"
    with open(image_path, "rb") as f:
        b64_data = base64.b64encode(f.read()).decode()
    payload["base64"] = f"data:{mime_type};base64,{b64_data}"

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {api_key}",
}
url = f"{DEFAULT_HOST}{endpoint}"
result = curl_post_json(url, payload, headers, timeout=120)

Technical Analysis

The default API endpoint uses HTTP rather than HTTPS. The script sends the API key in a Bearer authorization header and places user prompts and optional source images in the request body. Base64 encoding of an image only serializes binary content; it d ...[truncated 2344 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the default endpoint with an HTTPS endpoint whose certificate chains to a trusted certificate authority.
  2. Reject all non-HTTPS API URLs before transmitting credentials or user data.
  3. Do not provide an insecure HTTP fallback when TLS connection or certificate verification fails.
  4. Preserve curl's certificate verification and do not add --insecure or equivalent behavior.
  5. Update SKILL.md, install.md, and all reference documentation to show only the approved HTTPS endpoint.
  6. Consider certificate or public-key pinning if the deployment model can safely maintain pins.
  7. Rotate API keys that have already been used through the plaintext endpoint, because their confidentiality cannot be assured.
  8. Clearly inform users that prompts and source images are sent to the remote provider.

T09 · Insecure Skill Coding Practices

Error
Location
scripts/newapi-banana.py:369
Finding

Untrusted API Response Controls an Unrestricted Curl Download

Content
View full analysis

Vulnerability Details

File Location: scripts/newapi-banana.py:369-385
Vulnerability Type: Unvalidated remote URL and server-side request forgery behavior
Risk Level: High

Vulnerable Code

python
# Extract image URL from response
image_url = None
if resp.get("data") and len(resp["data"]) > 0:
    image_url = resp["data"][0].get("url")
elif resp.get("url"):
    image_url = resp["url"]

if not image_url:
    print("Error: No image URL in response", file=sys.stderr)
    print(json.dumps(resp, indent=2, ensure_ascii=False), file=sys.stderr)
    sys.exit(1)

# Download image
output_path = args.output or f"/tmp/openclaw/newapi-output/image_{int(time.time())}.png"
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
cmd = ["curl", "-s", "-S", "-L", "-o", output_path, "--max-time", "300", image_url]
dl = subprocess.run(cmd, capture_output=True, text=True)
if dl.returncode != 0:
    print(f"Download failed: {dl.stderr}", file=sys.stderr)
    sys.exit(1)

print(f"OUTPUT_FILE:{Path(output_path).resolve()}")

Technical Analysis

The script treats an image URL returned by the remote API as trusted and passes it directly to curl. It does not validate the URL scheme, destination hostname, resolved IP address, port, or response content type. The -L option also instructs curl to follow redirects without validating each redirect target.

A malicious, compromised, or impersonated API endpoint can therefore cause the local machine to issue requests to attacker-selected destinations. Since the primary API itself uses plaintext HTTP, an on-path attacker can also modify an otherwise legitimate response and inject an arbitrary URL.

Depending on curl's supported protocols and local network accessibility, a supplied URL could target loopback services, link-local addresses, private network services, cloud metadata endpoints, or local resources. Even when the resulting content is not returne ...[truncated 2091 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse the returned URL before invoking curl and permit only the https scheme.
  2. Maintain an explicit allowlist of approved image-delivery hostnames.
  3. Resolve the destination and reject loopback, private, link-local, multicast, reserved, and unspecified IP ranges for both IPv4 and IPv6.
  4. Protect against DNS rebinding by validating the address actually used for the connection, not only an earlier DNS lookup.
  5. Disable redirects unless required. If redirects are necessary, independently validate every redirect destination.
  6. Restrict curl protocols, for example with --proto =https and --proto-redir =https.
  7. Set a conservative maximum download size.
  8. Verify the response Content-Type and inspect the downloaded file's image signature before saving or delivering it.
  9. Decode and re-encode images with a hardened image library where practical, rather than forwarding arbitrary downloaded bytes.
  10. Use a dedicated egress policy or sandbox that prevents access to loopback, cloud metadata, and private-network destinations.

T09 · Insecure Skill Coding Practices

Warning
Location
references/api-key-setup.md:19
Finding

API-Key Setup Guidance Exposes Secrets Through Chat, Plaintext Configuration, and Command-Line Arguments

Content
View full analysis

Vulnerability Details

File Location: references/api-key-setup.md:19-50,76-80, install.md:9-35, and scripts/newapi-banana.py:450
Vulnerability Type: Insecure secret collection, storage, and command-line handling
Risk Level: Medium

Vulnerable Documentation and Code

references/api-key-setup.md:19-50 recommends storing the key directly in a JSON configuration file:

json
{
  "skills": {
    "entries": {
      "newapi-banana": {
        "apiKey": "your_api_key_here"
      }
    }
  }
}

references/api-key-setup.md:76-80 recommends entering the key into a conversation:

markdown
### Method 3: Provide it directly in the conversation

You can provide the API Key directly in the conversation for temporary use. For example:
- "My API Key is: sk-xxxxx"
- "Set API Key: your_key_here"

The executable also accepts the key as a command-line argument:

python
parser.add_argument("--api-key", "-k", help="API key (optional, resolved from config)")

The script reads the plaintext key from the configuration file:

python
def read_key_from_openclaw_config() -> str | None:
    cfg_path = Path.home() / ".openclaw" / "openclaw.json"
    if not cfg_path.exists():
        return None
    try:
        cfg = json.loads(cfg_path.read_text(encoding="utf-8"))
    except Exception:
        return None
    entry = cfg.get("skills", {}).get("entries", {}).get("newapi-banana", {})
    api_key = entry.get("apiKey")
    if isinstance(api_key, str) and api_key.strip():
        return api_key.strip()

Technical Analysis

Secrets entered into chat can be retained in conversation history, telemetry, model-provider logs, screenshots, exports, moderation systems, or backups. Advising users to disclose an API key through the conversation unnecessarily expands the number of systems that may receive it.

The recommended JSON configuration stores the API key ...[truncated 1950 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove all instructions asking users to send API keys in chat.
  2. Remove or deprecate the --api-key command-line option. Prefer a protected secret store or narrowly scoped environment injection.
  3. Integrate with the operating system's credential manager, OpenClaw's protected secret facility, or another encrypted secret-management service.
  4. If a plaintext configuration fallback is unavoidable, create the file with owner-only permissions and verify those permissions before reading it.
  5. Never overwrite an existing OpenClaw configuration merely to add this credential; use a safe merge process that preserves permissions and unrelated settings.
  6. Add documentation warning that API keys must not be pasted into conversations, source repositories, shell commands, screenshots, or shared logs.
  7. Redact credentials from all output and avoid displaying even prefixes unless they are operationally necessary.
  8. Recommend narrowly scoped, revocable API credentials and provide clear rotation instructions.
  9. Rotate any key previously disclosed through chat, command-line history, or an inadequately protected configuration 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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The guide explicitly tells users to send their API key directly in chat so the assistant can configure it for them. That creates an unnecessary credential-exposure path through conversational logs, prompt history, and any connected telemetry or third-party processing, which is especially risky in an agent skill context where chat may be persisted or inspected by other components.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The guide explicitly tells users they can provide their API key directly in chat, which creates a high-risk credential disclosure path through conversation logs, model retention, screenshots, or downstream integrations. In the context of an agent skill, this is especially dangerous because users may assume the chat channel is an approved secret input mechanism when it may not provide secure secret handling guarantees.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

This finding corresponds to the same unsafe behavior: the script directs the user toward sharing credentials in chat. In the agent context, that is a credential-access anti-pattern because it solicits secrets through a natural-language interface rather than a dedicated secure channel.

Content

Scanner excerpt · scripts/newapi-banana.py (reported line 84)May include surrounding context.

python
"error": "NO_API_KEY",
        "message": "No API key configured",
        "steps": [
            "1. Get API key from your NewAPI Banana service provider",
            "2. Send the key in chat or add to ~/.openclaw/openclaw.json: skills.entries.newapi-banana.apiKey",
        ],
    }

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The health-check message again encourages credential disclosure through chat, which can expose API tokens to logging, retention, or downstream model processing. This is a real vulnerability because it actively prompts insecure secret handling rather than merely supporting local credential reads.

Content

Scanner excerpt · scripts/newapi-banana.py (reported line 235)May include surrounding context.

python
"status": "no_key",
            "message": "No API key configured",
            "steps": [
                "1. Get API key from your NewAPI Banana service provider",
                "2. Send the key in chat or add to ~/.openclaw/openclaw.json: skills.entries.newapi-banana.apiKey",
            ],
        }, ensure_ascii=False))

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes shell commands, reads local reference files, and depends on environment variables, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates an overbroad execution surface where an agent may use capabilities beyond what reviewers or users expect, increasing the chance of unintended command execution or data access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill handles text prompts and user-supplied source images for generation/editing through an external API, but it does not warn users that their content will be transmitted off-platform. Users may unknowingly send sensitive personal, confidential, or regulated data to a third-party service, creating privacy, compliance, and data handling risks.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The persona section says all responses must follow rules including 'Speak Chinese,' which forces a specific language for all users. This is a natural-language locale policy issue because no opt-in, fallback, or justification for the restriction is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language instructions throughout the file are effectively forced to a single language, with no opt-in, alternative language option, or justification that the skill is intended only for a Chinese-speaking audience. That can violate a language/locale policy when users are not given a choice or informed of the constraint.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill encourages a natural-language workflow where users disclose their API key in chat, normalizing secret collection through the assistant. In a skill ecosystem, this is more dangerous because users may assume the agent is trusted, while the credential could be exposed to logs, plugins, operators, or future prompt reuse.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation normalizes sharing secrets in natural-language conversation, which increases the chance that API keys are exposed to the assistant, stored in logs, copied into transcripts, or observed by unintended parties. Although this overlaps with SQP-2, it is a distinct sensitive-data-handling issue because it trains users into an unsafe operational pattern for credential management.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

该技能文档整体仅以中文呈现,包括标题、步骤和注意事项,但未说明这是面向特定中文用户群的区域性工具,也未提供其他语言或用户选择语言的方式。根据语言/区域策略,强制单一语言而无用户选择或明确正当化,属于自然语言政策风险。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file presents all operational instructions and user-facing response examples exclusively in Chinese, including the required cost response text. The policy requires flagging language or locale constraints when a specific language is forced without user opt-in or clear justification.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The setup guidance explicitly tells the operator to send the API key in chat, creating a direct social path for secret disclosure to the agent or chat system. This is dangerous because it normalizes leaking long-lived credentials through conversational channels that may be logged, retained, or exposed to other components.

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/newapi-banana.py (reported line 105)May include surrounding context.

python
"--max-time", str(timeout), "-d", f"@{tmp_path}"]
        for k, v in headers.items():
            cmd += ["-H", f"{k}: {v}"]
        return subprocess.run(cmd, capture_output=True, text=True)
    finally:
        os.unlink(tmp_path)

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/newapi-banana.py (reported line 140)May include surrounding context.

python
"--max-time", str(timeout), "-d", f"@{tmp_path}"]
        for k, v in headers.items():
            cmd += ["-H", f"{k}: {v}"]
        return subprocess.run(cmd, capture_output=True, text=True)
    finally:
        os.unlink(tmp_path)

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/newapi-banana.py (reported line 175)May include surrounding context.

python
]
                    for k, v in headers.items():
                        cmd += ["-H", f"{k}: {v}"]
                    result = subprocess.run(cmd, capture_output=True, text=True)

            if result.returncode == 0:
                try:

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Allowing arbitrary host override extends the skill beyond its declared NewAPI target and creates a straightforward path to send authentication headers to untrusted infrastructure. In this context the danger is elevated because the same API key resolution logic pulls real credentials from config or environment and then reuses them against the supplied host.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The health-check output repeats the instruction to provide the API key via chat, reinforcing unsafe operator behavior and increasing the chance of credential leakage. Because this message appears during normal troubleshooting, it may pressure users into exposing secrets when the tool fails.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The health-check path allows an arbitrary --host-url and then sends the Bearer API key to that host. This enables credential exfiltration to any attacker-controlled server if the option is misused or socially engineered, which is especially dangerous because the feature exists outside the narrow image-generation need.

Content

Scanner excerpt · scripts/newapi-banana.py (reported line 251)May include surrounding context.

python
"--max-time", "10",
            "-H", f"Authorization: Bearer {key}",
        ]
        result = subprocess.run(cmd, capture_output=True, text=True)
        if result.returncode == 0:
            print(json.dumps({
                "status": "ready",

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script sends user prompts and optional image contents to a remote third-party API without explicit disclosure at execution time. In a skill context, users may unknowingly transmit sensitive text or local image data off-system, creating privacy and confidentiality risk rather than classic code-execution risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

The script downloads a URL returned by the remote API and writes it to a user-controlled output path without validating the destination or the downloaded content. In the skill context, this lets an external service influence local file writes and could overwrite files or plant unexpected content on disk if the operator supplies a sensitive path.

Content

Scanner excerpt · scripts/newapi-banana.py (reported line 428)May include surrounding context.

python
output_path = args.output or f"/tmp/openclaw/newapi-output/image_{int(time.time())}.png"
    Path(output_path).parent.mkdir(parents=True, exist_ok=True)
    cmd = ["curl", "-s", "-S", "-L", "-o", output_path, "--max-time", "300", image_url]
    dl = subprocess.run(cmd, capture_output=True, text=True)
    if dl.returncode != 0:
        print(f"Download failed: {dl.stderr}", file=sys.stderr)
        sys.exit(1)

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The manifest hard-codes locale-specific fields for Chinese and English names and does not indicate that language selection is optional or user-driven. This can conflict with a language/locale policy requiring explicit user choice rather than assuming only fixed locales.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The natural-language content forces a specific language for all users, and the file does not indicate that Chinese is optional or required for a region-specific reason. Under the policy, a fixed language without user opt-in can be a locale-policy violation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The manifest describes an image-generation skill, but the code also implements credential discovery by reading ~/.openclaw/openclaw.json and the NEWAPI_API_KEY environment variable. While common for CLI tooling, this is still a separate capability involving local configuration and environment access that is not stated in the manifest description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The code reads API keys from ~/.openclaw/openclaw.json and the NEWAPI_API_KEY environment variable, which are sensitive sources. There is no accompanying comment, help text, or user-facing notice explaining that credentials will be loaded from these locations.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.