T09 · Insecure Skill Coding Practices
- Location
scripts/openai_client.py:108- Finding
Unrestricted Provider-Supplied URL Fetch Enables SSRF and Resource Exhaustion
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill mostly does what it claims, but it handles API credentials, custom provider URLs, external image downloads, and output file writes with weak scoping controls.
Review before installing. Use only trusted HTTPS provider endpoints, prefer separate low-privilege API keys for proxies, avoid sensitive unpublished titles or topics, and write outputs to a dedicated directory with simple filenames. Do not let untrusted content choose --base-url, --api-key, --filename, or --output-dir values.
scripts/openai_client.py:108Unrestricted Provider-Supplied URL Fetch Enables SSRF and Resource Exhaustion
scripts/generate.py:389Unchecked Output Filename Permits Path Traversal and Arbitrary File Overwrite
scripts/generate.py:335API Credentials Can Be Sent to Arbitrary or Plaintext OpenAI-Compatible Endpoints
The code does perform image generation via Gemini, which partially aligns with the description. However, the declared purpose specifically emphasizes generating WeChat official account cover images with a proper 2.35:1 aspect ratio and supporting both OpenAI DALL-E and Gemini with customizable styles. This code chunk only implements a Gemini client, maps a few size presets, calls the Gemini API, and saves the resulting image. It does not enforce, crop, resize, or validate a 2.35:1 aspect ratio, and it contains no DALL-E integration. Any style support is only implicit through the prompt string, not through explicit customizable style features. Therefore, the code's actual behavior is narrower and materially missing key declared functionality.
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
AVOID:
No text, no letters, no numbers, no watermarks, no logos, no UI elements, no people's faces, no photorealistic rendering, no dark backgrounds, no neon colors, no cluttered compositions, no heavy shadows, no 3D perspective distortion. The image must be clean enough to serve as a professional magazine cover."""
return prompt.strip()
def generate_filename(title: str) -> str:
The skill documentation describes execution of a Python script that uses environment variables, writes image files, and makes network calls to external providers, but the skill declares no tool scope or permissions. This creates an avoidable trust gap: users and hosting systems are not explicitly warned that the skill can access secrets and send data off-box, which increases the chance of unintended credential exposure or overbroad execution.
The skill encourages use of OpenAI, Gemini, and custom OpenAI-compatible proxies, but does not clearly warn that article titles/topics and possibly API credentials or request metadata may be sent to third parties. This is dangerous because users may provide sensitive unpublished content or route requests through untrusted proxies without understanding the confidentiality and supply-chain risks.
This code resolves API keys from CLI arguments, settings.json, or environment variables and then sends the generated prompt and related request data to an external provider via client.generate(). While the script prints a basic summary, it does not explicitly disclose that user inputs are transmitted to a third-party API or that credentials from local configuration/environment will be used.
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
{
"openai": {
"api_key": "your-openai-api-key",
"base_url": "https://api.openai.com/v1",
"model": "dall-e-3"
},
"gemini": {
The manifest describes a cover-image generator supporting OpenAI and Gemini providers, but does not mention credential discovery from process environment variables or a local settings file. While using provider APIs is expected, implementing secret lookup from ambient environment and config storage is a broader capability than the stated end-user purpose of generating cover images.
This code creates parent directories and writes image bytes to the provided filename, which can modify the local filesystem. While file output is part of an image generation client's function, this file itself provides no confirmation prompt, user-facing log, or inline warning that a write will occur.