T09 · Insecure Skill Coding Practices
- Location
pollinations_image_gen.py:91- Finding
Pollinations API Key Exposed in URL Query Parameters
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly does what it claims, but its API-key handling and file-output controls create review-worthy risks before installation.
Review before installing. Use a low-privilege API key, avoid private prompts, keep outputs in a trusted directory that other users cannot write to, and avoid --telegram unless you intentionally want the generated image and prompt-derived caption sent to that chat. Prefer a version that authenticates with headers, hardens output path handling, and pins dependencies.
pollinations_image_gen.py:91Pollinations API Key Exposed in URL Query Parameters
pollinations_image_gen.py:111Output Directory Restrictions Can Be Bypassed Through Symbolic Links
requirements.txt:1Dependencies Are Installed Without Exact Version or Integrity Pinning
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
---
name: pollinations-ai
description: Generate images, music, and video using Pollinations AI API. Use when: (1) User wants to create images from text prompts, (2) User wants to generate music/audio, (3) User wants to create videos from text, (4) Using AI image generation with models like flux, zimage, nanobanana.
---
# Pollinations AI - Image, Music & Video Generation
The skill mixes and relies on Chinese/Cantonese user-facing messages such as the docstring, error text, and CLI help without any opt-in or alternative locale. This creates a language policy issue because the skill assumes a specific language for interaction rather than offering a user-selectable or documented locale.
This image-generation skill includes an additional outbound messaging capability that can send generated files and prompt-derived captions to Telegram. Even though it requires an explicit flag and environment variable, bundling unrelated exfiltration functionality into the same skill expands the data-exposure surface and makes accidental or unauthorized transmission more plausible.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if caption:
cmd.extend(["--message", caption])
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print(f"Image sent via Telegram: {image_path}")
return True
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
if caption:
cmd.extend(["--message", caption])
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
print(f"Image sent via Telegram: {image_path}")
return True
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
payload = {
"model": "openai",
"messages": [
{"role": "system", "content": "Rewrite as high-quality English image prompt. Raw text only."},
{"role": "user", "content": prompt}
]
}
The system message explicitly instructs the model to rewrite user input as an English image prompt. This imposes a specific language choice in natural-language behavior without offering the user an opt-in or alternative locale, which matches the language/locale policy violation criteria.
The enhance_prompt feature transmits user-supplied prompt content to an external API, which can expose sensitive or proprietary text if users include it in their prompts. In a skill context, outbound transmission of user input is a real data-leak risk unless clearly disclosed and consented to.
]
}
response = requests.post(self.text_api_url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.
import shutil
safe_output = os.path.join(workspace_path, "outputs", os.path.basename(args.output))
os.makedirs(os.path.dirname(safe_output), exist_ok=True)
shutil.copy(args.output, safe_output)
args.output = safe_output
print(f"Copied to allowed directory: {safe_output}")
The file contains docstrings, error messages, and CLI help text in Traditional Chinese/Cantonese only, such as the prompt help and validation error text. This imposes a language choice on users without any opt-in or alternative locale support, which matches the language/locale policy violation category.
The file is presented as an image generator CLI, but enhance_prompt sends user prompts to a chat-completions endpoint to rewrite them before image generation. This adds a distinct text-generation and outbound data-sharing capability that is not obviously required by a minimal image-generation tool, especially when no manifest declares it.
The dependency 'requests' is not version-pinned, which makes builds non-reproducible and can cause the environment to install an unexpectedly vulnerable or incompatible release. In a security context, leaving versions open also makes it impossible to verify whether known vulnerable versions are excluded.
requests
Pillow
The manifest references 'requests' without a version while the package has multiple known advisories across its release history. Because the version is unspecified, the project may install a vulnerable release and reviewers cannot determine from this file alone whether the dependency is safe.
The dependency 'Pillow' is not version-pinned, so installations may resolve to different versions over time, including versions with known security flaws or breaking behavior. This weakens supply-chain control and prevents reliable auditing of what code will actually be installed.
requests
Pillow
The manifest references 'Pillow' without a fixed version even though Pillow has had multiple security advisories, including memory-safety and resource-consumption issues. Without pinning, deployments may pull an affected version, especially in fresh or rebuilt environments.
No suspicious patterns detected.