Back to skill

Security audit

Cn Meme Generator

Security checks for vulnerabilities and agentic risk

Overview

This skill is a small meme image generator whose file writing and optional Pollinations network call match its stated purpose, with privacy and response-validation caveats.

Install only if you are comfortable with a Chinese-language meme tool. Use text mode for offline generation. In AI mode, avoid sensitive prompts because they are sent to Pollinations, and choose output paths carefully because the script writes the generated file directly.

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/cn_meme_generator.py:140
Finding
Unbounded and Unvalidated Remote Image Response<![CDATA[ ## Vulnerability Details **File Location**: `scripts/cn_meme_generator.py`, lines 140-144 **Vulnerability Type**: Unrestricted remote response buffering and missing content validation **Risk Level**: Medium ```python resp = requests.get(url, timeout=30) if resp.status_code == 200: with open(output, 'wb') as f: f.write(resp.content) ``` ### Technical Analysis The AI image generation path retrieves content from an external service and accesses `resp.content`, which buffers the complete response in memory. The configured 30-second timeout limits network waiting periods but does not impose a maximum response size. The program accepts every HTTP 200 response without checking its `Content-Type`, declared length, actual byte count, image format, or whether Pillow can safely decode it. It then writes those bytes directly to the caller-selected output file. Consequently, a compromised, malicious, or malfunctioning external service can return an oversized payload or arbitrary non-image content. Saving arbitrary bytes does not itself execute them, and the remote service cannot independently select the destination path. Exploitation is therefore primarily a resource-exhaustion and content-integrity risk rather than remote code execution. ### Attack Path 1. A user invokes the script in AI mode with a prompt. 2. The script sends the prompt to the Pollinations image endpoint. 3. The endpoint, or a compromised component in its delivery chain, returns HTTP 200 with an excessively large or non-image response. 4. `requests` buffers the complete response through `resp.content`, consuming memory without an application-level size limit. 5. The script writes the entire response to the selected output path, consuming disk space and presenting unverified bytes as an image. 6. The process may become unavailable due to memory or storage exhaustion, or downstream software may later process an invalid or hostile image payload. ### Impact Assessment Exploitatio ...[truncated 628 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use `stream=True` and read the response in fixed-size chunks. 2. Reject responses whose `Content-Length` exceeds a conservative image size limit, while also enforcing the limit during streaming because the header can be absent or dishonest. 3. Require an allowlisted image media type, such as `image/png`, `image/jpeg`, or `image/webp`. 4. Download into a securely created temporary file rather than writing directly to the final destination. 5. Open the temporary file with Pillow and call `verify()` to confirm that it contains a supported image. 6. Enforce image dimension and decompressed-pixel limits to mitigate decompression-bomb payloads. 7. Atomically move the validated file to the requested destination only after all checks succeed. 8. Delete partial temporary files on every failure path and report a concise error. Example hardening pattern: ```python import os import tempfile from PIL import Image, UnidentifiedImageError MAX_DOWNLOAD_BYTES = 10 * 1024 * 1024 ALLOWED_CONTENT_TYPES = {"image/png", "image/jpeg", "image/webp"} Image.MAX_IMAGE_PIXELS = 25_000_000 with requests.get(url, timeout=(5, 30), stream=True) as resp: resp.raise_for_status() content_type = resp.headers.get("Content-Type", "").split(";", 1)[0].lower() if content_type not in ALLOWED_CONTENT_TYPES: raise ValueError("The remote service returned an unsupported content type") declared_size = resp.headers.get("Content-Length") if declared_size and int(declared_size) > MAX_DOWNLOAD_BYTES: raise ValueError("The remote image exceeds the permitted size") output_dir = os.path.dirname(os.path.abspath(output)) fd, temporary_path = tempfile.mkstemp(dir=output_dir, suffix=".download") try: received = 0 with os.fdopen(fd, "wb") as temporary_file: for chunk in resp.iter_content(chunk_size=64 * 1024): if not chunk: continue received += len( ...[truncated 431 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
The skill's description, CLI messages, and help text are presented in Chinese only, which imposes a specific language/locale without offering the user a choice. Under the stated policy, forcing a language without opt-in is a natural-language policy violation unless the locale restriction is clearly justified.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
current = ''
        for char in words:
            test = current + char
            bbox = __import__('PIL').ImageDraw.ImageDraw.textbbox
            # 简单判断
            try:
                test_bbox = __import__('PIL').ImageDraw.ImageDraw.textbbox((0,0), test, font=font)
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
bbox = __import__('PIL').ImageDraw.ImageDraw.textbbox
            # 简单判断
            try:
                test_bbox = __import__('PIL').ImageDraw.ImageDraw.textbbox((0,0), test, font=font)
                if test_bbox[2] - test_bbox[0] <= max_width:
                    current = test
                else:
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
In AI mode, user-supplied prompt text is sent to an external service (image.pollinations.ai) without any explicit notice, consent, or data-handling warning. If users include sensitive personal, internal, or proprietary information in prompts, the tool may unintentionally disclose that data to a third party.

Natural-Language Policy Violations

Low
Confidence
83% confidence
Finding
The natural-language instructions and examples are presented only in Chinese, which can amount to forcing a specific language without user opt-in. There is no statement that the skill is intended specifically for Chinese-speaking users or that alternative language support is unavailable by design.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The markdown states that AI mode uses the Pollinations API and that the image is automatically saved, but it does not clearly warn users that their prompt is sent to a third-party service or that a local file will be written as part of the operation. Because this skill description covers network transmission and file output, a clearer user-facing warning is warranted.

Static analysis

No suspicious patterns detected.