Back to skill

Security audit

Pollinations

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it has under-disclosed local-file upload behavior and a URL-handling flaw that could disclose local files.

Review before installing. Use this skill only with prompts and media you are comfortable sending to external AI services. Avoid local image editing unless you accept upload through a temporary public host, and do not let untrusted instructions choose transcription inputs because file:// style inputs could expose readable local files.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/image-edit.sh:85
Finding
Undisclosed Upload of Local Images to a Third-Party Temporary Hosting Service<![CDATA[ ## Vulnerability Details **File Location**: `scripts/image-edit.sh`, lines 85-98 **Vulnerability Type**: Undisclosed third-party data disclosure **Risk Level**: Medium ### Vulnerable Code ```bash if [[ -f "$SOURCE" ]]; then # Local file: upload to temp host to get a URL, then use GET endpoint # (Pollinations image API is GET-only, no POST support) echo "Uploading local file to temporary host..." TEMP_URL=$(curl -s -F "reqtype=fileupload" -F "time=1h" -F "fileToUpload=@$SOURCE" https://litterbox.catbox.moe/resources/internals/api.php) if [[ -z "$TEMP_URL" || ! "$TEMP_URL" =~ ^https?:// ]]; then echo "Error: Failed to upload local file. Please provide a URL instead." echo "Example: image-edit.sh \"$PROMPT\" --source https://example.com/image.jpg" exit 1 fi echo "Uploaded: $TEMP_URL" SOURCE="$TEMP_URL" fi ``` ## Technical Analysis When a local image is supplied to the image-editing script, the file is uploaded to `litterbox.catbox.moe` before Pollinations processes it. The primary documentation states that local files are accepted but does not clearly disclose that local images will be transferred to an additional temporary hosting provider. The script's usage message at line 72 also states that local files are uploaded to `0x0.st`, while the implemented destination is Litterbox. This discrepancy prevents users from accurately identifying the external party receiving their data. The returned URL is accepted when it merely begins with `http://` or `https://`. The script does not verify that the returned hostname belongs to the expected service, does not require HTTPS, and does not provide an explicit consent checkpoint before uploading potentially sensitive content. ### Attack Path 1. A user or agent invokes `scripts/image-edit.sh` with a local image through the `--source` option. 2. The script recognizes the argument as an existing local file. 3. The file is uploaded in full to `https://litterbox.catbox.moe/resources/ ...[truncated 935 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer a direct authenticated upload to Pollinations rather than using a public temporary hosting service. 2. If third-party hosting is unavoidable, obtain explicit user consent before every upload and clearly identify: - The exact service receiving the file. - Whether the resulting URL is public. - The expected retention period. - Any applicable privacy policy. 3. Correct the inaccurate `0x0.st` statement so that documentation and runtime help identify the actual destination. 4. Require an HTTPS response URL and validate its parsed hostname against an explicit allowlist. 5. Reject redirects to unapproved hosts by applying an appropriate redirect policy. 6. Validate file type and size before upload and reject files outside the documented image formats. 7. Avoid printing the complete hosted URL where logs could expose access to the uploaded image. 8. Provide a mode that rejects local files and requires users to supply a URL under their own control. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/transcribe.sh:55
Finding
Arbitrary URI Scheme Handling Enables Local File Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/transcribe.sh`, lines 55-65 and 87-90 **Vulnerability Type**: Unrestricted URI scheme and local file disclosure **Risk Level**: High ### Vulnerable Code ```bash if [[ -f "$AUDIO_INPUT" ]]; then FORMAT=$(detect_format "$AUDIO_INPUT") base64 -w0 "$AUDIO_INPUT" > "$B64_FILE" else # URL: download first echo "Downloading audio..." TEMP_AUDIO=$(mktemp /tmp/audio_dl_XXXXXX) trap "rm -f '$BODY_FILE' '$B64_FILE' '$TEMP_AUDIO'" EXIT curl -s -o "$TEMP_AUDIO" "$AUDIO_INPUT" FORMAT=$(detect_format "$AUDIO_INPUT") base64 -w0 "$TEMP_AUDIO" > "$B64_FILE" fi ``` The downloaded data is subsequently transmitted to Pollinations: ```bash RESPONSE=$(curl -s --max-time 300 -H "Content-Type: application/json" \ ${POLLINATIONS_API_KEY:+-H "Authorization: Bearer $POLLINATIONS_API_KEY"} \ -X POST "https://gen.pollinations.ai/v1/chat/completions" \ -d @"$BODY_FILE") ``` ## Technical Analysis Any input that is not recognized by `[[ -f "$AUDIO_INPUT" ]]` is treated as a remote URL and passed directly to `curl`. No URL parser or protocol allowlist restricts the accepted scheme. By default, curl supports schemes other than HTTP and HTTPS, including `file://`. A value such as `file:///etc/passwd` is not recognized by Bash as a regular path because it contains the URI prefix, but curl can resolve it as a local file. The retrieved bytes are written to a temporary file, Base64-encoded, embedded in the request body, and transmitted to Pollinations. The code also lacks meaningful validation that downloaded content is audio. Format detection is based only on the supplied string's extension and defaults to MP3, so arbitrary process-readable content can be labeled as audio and sent externally. ### Attack Path 1. An attacker influences the argument passed to `scripts/transcribe.sh`, such as through an untrusted agent instruction or an application that exposes the script arguments. 2. The attacker supplies a ...[truncated 1229 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse input URLs and allow only HTTPS: ```bash case "$AUDIO_INPUT" in https://*) ;; http://*) echo "Error: HTTPS is required"; exit 1 ;; *://*) echo "Error: Unsupported URI scheme"; exit 1 ;; esac ``` 2. Enforce curl protocol restrictions independently of application validation: ```bash curl --fail --show-error --proto '=https' --proto-redir '=https' \ -o "$TEMP_AUDIO" "$AUDIO_INPUT" ``` 3. Treat local paths and remote URLs as distinct input types. Never convert a `file://` URI into an accepted local path. 4. Validate local files as regular, non-symlink audio files where appropriate, and restrict them to explicitly permitted locations if the calling environment requires isolation. 5. Verify downloaded content using file signatures or a trusted media parser rather than relying on the filename extension. 6. Apply maximum download and local-file size limits before Base64 encoding to prevent resource exhaustion. 7. Reject empty downloads, non-audio content, redirects to unapproved schemes, and curl failures before constructing the API request. 8. Consider requiring explicit confirmation before transmitting any local file to an external service. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (42)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The supplied code implements only a text chat/completions client for the Pollinations API. It constructs a messages array, posts to the chat completions endpoint, and extracts textual response content. There is no evidence in this chunk of image, video, audio, vision-analysis, or transcription functionality. While using Pollinations.ai is accurately represented, the declared description materially overstates the implemented capabilities of this specific code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description describes a comprehensive Pollinations.ai skill covering text, images, videos, audio, analysis, and transcription via OpenAI-compatible endpoints. The supplied code chunk is much narrower: it only handles media generation by constructing a GET request to the Pollinations image endpoint and saving the returned file locally. It may incidentally support video output for certain models and includes an audio query flag, but there is no implementation for text generation, analysis, transcription, or general API coverage. Therefore the description materially overstates the skill's actual behavior for this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
The declared description presents a full-featured Pollinations.ai integration for generation and analysis tasks across multiple modalities. In contrast, this code chunk is a utility script whose sole function is to fetch and print model identifiers from Pollinations endpoints, with some hardcoded fallback model names. It does not call generation, analysis, or transcription endpoints, accept user content, or perform any AI task itself. While model listing is related to the Pollinations ecosystem, it is a materially narrower and different purpose than the declared end-user capabilities.

External Model or Provider Selection

High
Category
Excessive Agency
Content
**Usage:**
```bash
scripts/chat.sh "your message"
scripts/chat.sh "your message" --model claude --temp 0.7
scripts/chat.sh "explain quantum physics" --model openai --max-tokens 500
scripts/chat.sh "list 3 colors" --json --model openai
scripts/chat.sh "solve this step by step" --model o3 --reasoning-effort high
Confidence
90% confidence
Finding
The skill allows selecting named external models such as Claude through a third-party integration, but does not explain routing, trust boundaries, or whether prompts may be forwarded to additional providers. In this context, external model selection can expose user data to different vendors with different handling policies, which is a real privacy and governance risk.

External Model or Provider Selection

High
Category
Excessive Agency
Content
scripts/chat.sh "explain quantum physics" --model openai --max-tokens 500
scripts/chat.sh "list 3 colors" --json --model openai
scripts/chat.sh "solve this step by step" --model o3 --reasoning-effort high
scripts/chat.sh "translate to French" --system "You are a translator" --model gemini
```

**Options:**
Confidence
90% confidence
Finding
The Gemini example reinforces that prompts can be routed to alternate external providers without explicit trust or privacy disclosures. Because the skill is broadly activatable, users may not realize their content is leaving the primary environment and being processed by a different vendor.

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 2. Image Generation (`scripts/image.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 3. Image Editing / Image-to-Image (`scripts/image-edit.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 3. Image Editing / Image-to-Image (`scripts/image-edit.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 3. Image Editing / Image-to-Image (`scripts/image-edit.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
### 3. Image Editing / Image-to-Image (`scripts/image-edit.sh`)
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

External Model or Provider Selection

High
Category
Excessive Agency
Content
```bash
scripts/analyze-image.sh "https://example.com/photo.jpg"
scripts/analyze-image.sh photo.jpg --prompt "What objects are in this image?"
scripts/analyze-image.sh image.png --model claude --prompt "Extract all text from this image"
```

**Options:**
Confidence
90% confidence
Finding
This example combines external provider selection with image analysis of local files, which can transmit sensitive visual data to a third-party model provider such as Claude. The context makes this more dangerous than ordinary text prompting because images may contain IDs, documents, faces, screens, or other high-sensitivity content.

External Model or Provider Selection

High
Category
Excessive Agency
Content
```bash
scripts/analyze-video.sh "https://example.com/video.mp4"
scripts/analyze-video.sh recording.mp4 --prompt "Summarize the key moments"
scripts/analyze-video.sh clip.mov --model gemini-large --prompt "Count the people"
```

**Options:**
Confidence
90% confidence
Finding
The skill documents sending video content to a selected external model, which may reveal sensitive scenes, people, locations, or business activity to third-party providers. Video often contains more contextual and biometric data than text, so provider-routing ambiguity significantly increases privacy risk.

External Model or Provider Selection

High
Category
Excessive Agency
Content
**Usage:**
```bash
scripts/transcribe.sh recording.mp3
scripts/transcribe.sh podcast.wav --model gemini-large
scripts/transcribe.sh "https://example.com/audio.mp3" --prompt "Transcribe in French"
```
Confidence
90% confidence
Finding
Audio transcription with a selectable external model can expose voiceprints, conversations, and confidential meetings to a third-party provider. In this skill, the risk is elevated because the documentation encourages use with local files but does not pair that with strong data-transfer warnings or provider transparency.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
When the user provides a local file, the script silently uploads that file to litterbox.catbox.moe, an unrelated third-party host, making the image accessible outside the user's local environment. This is a clear data exfiltration/privacy risk because users may pass sensitive screenshots, identity documents, or internal images, and the skill context encourages routine AI image editing where such content is plausible.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill documents shell-based scripts and package installation steps but does not declare an explicit tool scope such as allowed-tools or permissions. That creates an authorization ambiguity where an agent may invoke shell capabilities more broadly than reviewers or users expect, increasing the chance of unintended command execution.