Back to skill

Security audit

Gemini Painter

Security checks for vulnerabilities and agentic risk

Overview

This skill is a narrowly scoped image-generation helper that uses a documented local API and saves generated images, with some configuration and disclosure gaps users should understand.

Install this only if you trust the local service listening on 127.0.0.1:8317, because your image prompts are sent there and generated images are saved under your .openclaw workspace. Avoid putting private information in prompts unless that backend is trusted, and treat the embedded OpenClaw bearer value as non-secret or rotate it if the service relies on it for access control.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/painter.py:12
Finding

Hardcoded Bearer Credential for Local Image API

Content
View full analysis

Vulnerability Details

File Location: scripts/painter.py, lines 12–13 and 20–23
Vulnerability Type: Hardcoded credential
Risk Level: Medium

Vulnerable Code

python
BASE_URL = "http://127.0.0.1:8317/v1"
API_KEY = "OpenClaw"
python
headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {API_KEY}"
}

Technical Analysis

The source code embeds the static bearer credential OpenClaw and sends it in the Authorization header when accessing the local image-generation API. Any user or process capable of reading the distributed Skill can recover and reuse this credential.

The loopback destination limits exposure to the local host, and the audited code does not transmit the credential to an external server. Nevertheless, a hardcoded shared token provides no meaningful secrecy, rotation, revocation, or per-user isolation. Its effective scope depends on the permissions granted by the service listening on TCP port 8317.

Attack Path

  1. An attacker obtains read access to the Skill package or its source code.
  2. The attacker reads scripts/painter.py and extracts the bearer token OpenClaw.
  3. From the same host, the attacker connects to 127.0.0.1:8317.
  4. The attacker submits requests with Authorization: Bearer OpenClaw.
  5. If the local service accepts the token, the attacker invokes any API operations authorized for that credential.

This path requires local access to the API because the configured endpoint is bound to the loopback address. Whether the service is independently exposed through another interface is outside the reviewed project.

Impact Assessment

A local attacker may submit unauthorized image-generation requests, consume model or computational resources, and invoke other operations exposed by the local API if the shared credential authorizes them. The reviewed code does not establish system-level privilege escalation, external credential exfiltration, or remote code executio ...[truncated 289 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the bearer credential from source code and version control.
  2. Load the credential from a protected environment variable or operating-system secret store.
  3. Fail closed with a clear configuration error when a required credential is absent.
  4. Issue a unique, revocable token scoped only to image generation and apply rate limits where supported.
  5. Restrict access to the secret and the local API to the specific account or process that runs the Skill.
  6. Rotate or revoke the embedded OpenClaw credential because it must be treated as disclosed.
  7. If the loopback service intentionally requires no authentication, remove the ineffective bearer-token mechanism rather than distributing a shared token.
  8. Prefer authenticated local IPC or enforce a strict loopback binding and service-level authorization to reduce unauthorized local use.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (7)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises networked code execution behavior via a local HTTP endpoint and likely environment access, but it does not declare any explicit tool scope or permissions boundary. This creates a capability mismatch: users and the host system cannot clearly constrain or review what external access the skill requires, increasing the risk of unintended network use, secret exposure, or privilege creep if the backing script evolves.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The invocation examples are framed as natural everyday requests without clear trigger boundaries, exclusions, or confirmation requirements. In an agentic environment, this can cause over-broad activation or accidental invocation during normal conversation, which may lead to unintended image generation, unnecessary network calls, and unreviewed file writes to the archive directory.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The function docstring states it uses the Gemini Imagen 3 interface to generate images, but the implementation targets /chat/completions and sets MODEL = "gemini-3-pro-image" rather than an Imagen 3-specific API/model. This is an active documentation-to-code mismatch about the underlying service being used, not merely an omitted detail.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The skill transmits the full user prompt to an HTTP API endpoint, creating an external data exposure path for potentially sensitive user input. Although the endpoint is localhost, the use of plain HTTP and dependence on a local service means prompts can still be disclosed to an untrusted local proxy/service or logged by that backend without user awareness.

Content

Scanner excerpt · scripts/painter.py (reported line 36)May include surrounding context.

python
}
    
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=120)
        if response.status_code != 200:
            return {"status": "error", "message": f"API returned status {response.status_code}"}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code creates directories and writes generated image bytes to a persistent path under the user's profile, but there is no confirmation prompt, warning print, or user-facing disclosure around this file write. The docstring describes image generation but does not clearly warn that files will be saved automatically to disk in a default location.

Content

No source excerpt is available for this finding.

Tainted flow: 'output_path' from os.environ.get (line 57, credential/environment) → open (file write)

Medium
Category
Data Flow
Confidence
92% confidence
Finding

The file write path is derived from the USERPROFILE environment variable and then used directly in os.makedirs/open without validating that it stays within an expected archive directory. In an agent or launcher context where environment variables can be influenced, this can redirect writes to unintended filesystem locations and enable overwriting or planting files outside the intended workspace.

Content

Scanner excerpt · scripts/painter.py (reported line 62)May include surrounding context.

python
# 确保目录存在
                    os.makedirs(os.path.dirname(output_path), exist_ok=True)
                    
                    with open(output_path, "wb") as f:
                        f.write(image_bytes)
                    
                    return {

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The function docstring is written only in Chinese, which indicates a language-specific presentation without offering user choice or documenting a locale-specific requirement. This can violate language or locale policy when a skill imposes one language by default without opt-in.

Content

No source excerpt is available for this finding.