T09 · Insecure Skill Coding Practices
- Location
scripts/wangyi-banana.py:153- Finding
API Key Exposure Through Command-Line Arguments and Insecure Setup Guidance
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This media-generation skill appears to do what it claims, but it unsafely asks users to share API keys in chat and handles credentials and saved outputs in ways users should review before installing.
Before installing, do not paste an API key into chat. Use a restricted environment variable or local OpenClaw config instead, rotate any key already shared conversationally, avoid confidential prompts or personal media unless you trust the WangYi Banana service, and keep outputs in the default temporary directory unless you intentionally choose another path.
scripts/wangyi-banana.py:153API Key Exposure Through Command-Line Arguments and Insecure Setup Guidance
Telling users to paste an API key directly into chat creates a clear secret-handling vulnerability. In the context of an agent skill, chat content may be retained, inspected, replayed, or accessible to plugins and operators, turning a convenience step into a credential exposure path.
The instruction to paste the API key into the assistant directly is a classic secret-disclosure anti-pattern. Because this skill already relies on multiple remote services, exposing the key through chat increases the chance of account abuse, billing fraud, and downstream compromise if the credential is reused elsewhere.
The guide explicitly tells users they can provide their API key directly in chat, which encourages secret disclosure through a conversational channel that may be logged, retained, displayed to other components, or exposed in transcripts. In the context of an agent skill, this is especially risky because users may assume the chat is a safe secret-input mechanism when it often is not.
The credential-handling flow prompts the user toward sharing an API key in chat, which is an unsafe credential acquisition pattern. Even though the code does not exfiltrate secrets programmatically, the skill design solicits sensitive data through a potentially monitored interface.
"error": "NO_API_KEY",
"message": "No API key configured",
"steps": [
"1. Get API key from your WangYi Banana service provider",
"2. Send the key in chat or add to ~/.openclaw/openclaw.json: skills.entries.wangyi-banana.apiKey",
],
}
The script explicitly instructs users to send the API key in chat, encouraging disclosure of sensitive credentials through natural-language channels that may be logged, retained, or exposed to other tools. In an agent ecosystem, this materially increases the chance of credential leakage beyond the local machine.
This health-check messaging participates in insecure credential collection by telling the user to provide a secret via chat. In context, a skill that asks for API keys conversationally is more dangerous because users may trust the tool and unknowingly expose reusable credentials.
"status": "no_key",
"message": "No API key configured",
"steps": [
"1. Get API key from your WangYi Banana service provider",
"2. Send the key in chat or add to ~/.openclaw/openclaw.json: skills.entries.wangyi-banana.apiKey",
],
}, ensure_ascii=False))
The health-check path repeats the instruction to send API keys in chat, reinforcing insecure behavior at the exact point where users are troubleshooting credentials. Repetition makes accidental secret disclosure more likely, especially when users follow tool guidance verbatim.
The skill declares shell, file read/write, and environment-variable-dependent behavior but does not scope or constrain tool permissions in metadata. This increases the chance that an agent can execute broader-than-necessary actions, making misuse, prompt-injection chaining, or accidental access to sensitive files and secrets more likely.
Forcing all responses to be in Chinese without user opt-in can mislead or exclude users and may cause them to miss important safety, billing, or data-transfer disclosures. In this skill, that risk is amplified because users need to understand API-key usage, external network transmission, and media handling details clearly.
The skill discloses backup hosts only deep in the file and does not clearly warn users that prompts, images, videos, and API-key-authenticated requests may be sent to third-party endpoints, including a plain-HTTP host. This creates material confidentiality and integrity risk because sensitive user content and credentials could be transmitted to unexpected infrastructure without informed consent, and HTTP permits interception or modification in transit.
The skill asks users to use API keys with named third-party endpoints and generate images/videos, but does not clearly warn that prompts, images, and video inputs may be transmitted to external services. This can lead users to disclose sensitive text or media without informed consent, especially since the service appears to be a reseller or unofficial provider rather than a clearly identified first-party platform.
The documentation explicitly instructs users to send their API key through chat to another agent for configuration. This is dangerous because chat channels, agent memory, logs, telemetry, or prompt history may expose the credential to unintended parties or systems, enabling unauthorized use of the paid third-party API.
The file forces a specific language for all setup instructions, and there is no indication that the skill is region-specific or that users can opt into another language. Under the stated policy, a fixed language without user choice or documented justification is a natural-language policy issue.
This markdown file presents all user-facing instructions in a single language and does not indicate that the skill is intentionally limited to Chinese-speaking users or a region-specific context. Under the policy rule, forcing a specific language without user opt-in or justification is a natural-language policy violation.
The file presents all instructions in Chinese and later mandates specific Chinese response wording, which can amount to forcing a language without user opt-in. The policy allows locale constraints only when clearly documented and justified or when users are offered a language choice.
The guidance directs the skill to persist all generated outputs in a fixed local directory, but it does not disclose this storage behavior to users or define retention and cleanup expectations. This can create unintended data-at-rest exposure for user-provided or generated media, especially if outputs are sensitive and remain accessible on the host after task completion.
The line explicitly says the response should include 花了 ¥X.XX, which enforces Chinese output. This is a natural-language policy concern because it mandates a specific language rather than letting the user choose or documenting a justified locale restriction.
The documentation instructs users to upload reference images and character videos to generate content, but it does not disclose that these files will be transmitted to an external third-party video generation service. This creates a real privacy and data handling risk because users may submit sensitive or copyrighted media without informed consent about where the data is sent or processed.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"--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 calls execute external commands. Without careful input validation, this enables command injection.
"--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 calls execute external commands. Without careful input validation, this enables command injection.
]
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:
The skill automatically downloads generated media and writes it to local storage without a clear user-facing disclosure or confirmation. In an agent setting, silent file creation increases the risk of unexpected disk writes, privacy issues, and abuse of arbitrary output paths supplied by the caller.
The code retrieves an image URL from model output and downloads it directly to disk without trust checks on the URL or destination path. Because the source URL can be indirectly influenced by external services, this creates a file-write and untrusted-download risk in an agent skill that may run unattended.
output_path = args.output or f"/tmp/openclaw/wangyi-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]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Download failed: {result.stderr}", file=sys.stderr)
sys.exit(1)
The script downloads a URL returned by a remote API directly to a user-chosen local path with curl, without validating the scheme, host, content type, or destination safety. In a skill context, this can overwrite arbitrary files writable by the current user or fetch unexpected content from attacker-controlled URLs if the upstream service is compromised or abused.
output_path = args.output or f"/tmp/openclaw/wangyi-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]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
print(f"Download failed: {result.stderr}", file=sys.stderr)
sys.exit(1)
Video generation results are saved to disk automatically, which can surprise users and create persistent local artifacts without warning. This is especially relevant for agent skills because they may be triggered indirectly and write large files to locations chosen by inputs.