Back to skill

Security audit

Minimax Image Gen

Security checks for vulnerabilities and agentic risk

Overview

This MiniMax image-generation skill does what it claims, but it handles API keys and downloads with insecure TLS and weak download validation, so users should review it before installing.

Review before installing. Use only a restricted MiniMax API key, avoid confidential prompts, and prefer a fixed version that preserves normal TLS certificate validation and validates downloaded image URLs and sizes. Be aware that --preview opens generated files in local viewer applications.

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

Error
Location
scripts/gen.py:237
Finding
TLS Certificate Verification Disabled for Credential-Bearing API Requests## Vulnerability Details **File Location**: `scripts/gen.py`, lines 237-245 **Vulnerability Type**: Improper TLS certificate validation **Risk Level**: High ### Vulnerable Code ```python ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE data = json.dumps(payload).encode("utf-8") try: req = urllib.request.Request(url, data=data, headers=headers, method="POST") with urllib.request.urlopen(req, context=ctx, timeout=120) as response: ``` The request headers constructed earlier contain the MiniMax API credential: ```python headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json", } ``` ### Technical Analysis The code creates a standard TLS context but then explicitly disables hostname checking and certificate verification. Consequently, the client does not verify that the remote endpoint presenting a certificate is the legitimate `api.minimaxi.com` service. The affected request carries the MiniMax API key in a bearer authorization header and includes the user's image prompt in its JSON body. HTTPS encryption alone does not provide endpoint authenticity when certificate validation is disabled. An attacker capable of intercepting or redirecting network traffic can present an arbitrary certificate, terminate the TLS connection, and receive both the credential and prompt. Sending the API key to the documented MiniMax API is necessary for the declared image-generation functionality. Disabling TLS verification is unnecessary and exceeds the minimum acceptable security posture for transmitting that secret. ### Attack Path 1. A user invokes the Skill to generate an image. 2. The Skill creates a POST request containing the bearer API key and user prompt. 3. An attacker with a network interception position, malicious proxy, or DNS-routing capability redirects the connection to an attacker-controlled endpoint. 4. The ...[truncated 977 chars]
Remediation
## Remediation Suggestions Preserve the secure defaults provided by Python's TLS implementation. Remove both overrides: ```python ctx = ssl.create_default_context() req = urllib.request.Request(url, data=data, headers=headers, method="POST") with urllib.request.urlopen(req, context=ctx, timeout=120) as response: result = json.loads(response.read().decode("utf-8")) ``` Additional hardening should include: - Never add an automatic fallback that disables certificate validation after a TLS error. - If a private trust chain is genuinely required, load a narrowly scoped and trusted CA bundle with `SSLContext.load_verify_locations()` rather than disabling verification. - Keep the API destination fixed to the documented HTTPS endpoint. - Avoid including secrets or complete server response bodies in error output. - Add a test confirming that untrusted, expired, and hostname-mismatched certificates are rejected. - Rotate the API key if the vulnerable implementation has been used on an untrusted network.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/gen.py:264
Finding
Unvalidated Server-Supplied Download URLs with Disabled TLS Verification and Unbounded Reads## Vulnerability Details **File Location**: `scripts/gen.py`, lines 264-278 **Vulnerability Type**: Unrestricted outbound request and unsafe remote-content download **Risk Level**: Medium ### Vulnerable Code ```python @staticmethod def download_image(url: str, filepath: Path) -> bool: """下载图片""" ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE try: req = urllib.request.Request(url) with urllib.request.urlopen(req, context=ctx, timeout=60) as response: filepath.parent.mkdir(parents=True, exist_ok=True) with open(filepath, "wb") as f: f.write(response.read()) return True except Exception as e: print(f"[ERROR] Download failed: {e}") return False ``` The function is called for every URL supplied in the API response: ```python for i, url in enumerate(urls, 1): filepath = output_dir / f"minimax-{timestamp}-{slug}-{i}.png" print(f"[{i}/{len(urls)}] Downloading...", end=" ") if generator.download_image(url, filepath): print("OK") saved.append(filepath) else: print("FAILED") ``` ### Technical Analysis The Skill accepts image URLs from a remote API response and passes them directly to `urllib.request.urlopen()` without validating the URL scheme, hostname, resolved address, port, or redirect destination. The downloader also disables TLS hostname and certificate verification. A malicious or intercepted API response can therefore instruct the process to request an attacker-selected endpoint, including potentially an internal service reachable from the host. The existing TLS weakness makes response manipulation a practical attack path for a network-positioned attacker. The implementation additionally calls `response.read()` without imposing a maximum response size. This loads the entire response into memory b ...[truncated 1663 chars]
Remediation
## Remediation Suggestions Harden the download workflow as follows: - Require the `https` scheme. - Allow only documented MiniMax image CDN hostnames. - Resolve destinations and reject loopback, link-local, private, reserved, and other disallowed address ranges where applicable. - Disable automatic redirects or validate every redirect destination against the same policy. - Use normal TLS certificate and hostname verification. - Stream the response in bounded chunks rather than calling an unrestricted `response.read()`. - Enforce a conservative maximum download size using both `Content-Length` and a running byte counter. - Require an expected image media type and verify the downloaded file's image signature before treating it as an image. - Delete partial files when validation or downloading fails. - Consider generating output extensions based on a verified image format rather than always using `.png`. A hardened implementation should follow this general pattern: ```python parsed = urllib.parse.urlparse(url) if parsed.scheme != "https" or parsed.hostname not in APPROVED_IMAGE_HOSTS: raise ValueError("Unapproved image URL") ctx = ssl.create_default_context() req = urllib.request.Request(url) total = 0 with urllib.request.urlopen(req, context=ctx, timeout=60) as response: content_type = response.headers.get_content_type() if content_type not in {"image/png", "image/jpeg", "image/webp"}: raise ValueError("Unexpected content type") with open(filepath, "wb") as output: while chunk := response.read(64 * 1024): total += len(chunk) if total > MAX_IMAGE_BYTES: raise ValueError("Image exceeds size limit") output.write(chunk) ```
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Lp3

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding
The skill advertises capabilities that imply environment access, file reading, networking, and shell execution, but it does not declare an explicit tool scope such as permissions or allowed-tools. That weakens least-privilege controls and makes it harder for users or the host platform to understand and constrain what the skill may do.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The documentation does not clearly warn users that their prompts and related request data will be transmitted to an external third-party image generation service. Users may unknowingly send sensitive, personal, or proprietary content off-platform, creating privacy and confidentiality risk.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill provides multiple ways to configure an API key, including inline JSON examples, but does not clearly warn users to keep credentials secret and avoid sharing, logging, or committing them to version control. This increases the chance of accidental credential exposure and downstream account misuse or billing abuse.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
The top-level natural-language description presents the skill as a Chinese-only "专属" image-generation skill and all user-facing descriptive metadata in this section is in Chinese, with no indication that other languages are supported or optional. This creates a locale/language policy concern because the skill appears to impose a specific language context without documenting user choice or a justified regional restriction.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill reads API credentials from unrelated OpenClaw configuration files, expanding its access beyond the declared MINIMAX_API_KEY environment variable. This creates a cross-context secret harvesting risk: a skill intended only for image generation can silently consume credentials stored for other tools or profiles, violating least privilege and potentially exposing or misusing sensitive keys.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if sys.platform == "win32":
                os.startfile(filepath)
            elif sys.platform == "darwin":
                subprocess.run(["open", str(filepath)], check=True)
            else:
                subprocess.run(["xdg-open", str(filepath)], check=True)
            print(f"[PREVIEW] Opened: {filepath.name}")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
elif sys.platform == "darwin":
                subprocess.run(["open", str(filepath)], check=True)
            else:
                subprocess.run(["xdg-open", str(filepath)], check=True)
            print(f"[PREVIEW] Opened: {filepath.name}")
        except:
            try:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Context-Inappropriate Capability

Low
Confidence
80% confidence
Finding
The preview feature can launch local applications or a browser, which exceeds the minimal scope of image generation and introduces side effects on the host. In this skill's context the opened files are generated downloads, so the danger is limited, but automatic opening of local resources can still surprise users, trigger external handlers, or broaden attack surface if untrusted file types or paths are ever introduced.

Static analysis

No suspicious patterns detected.