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

Content
View full analysis

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
View 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

Content
View full analysis

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
View 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)

Undeclared Tool Scope

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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/gen.py (reported line 322)May include surrounding context.

python
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}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/gen.py (reported line 324)May include surrounding context.

python
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:

Context-Inappropriate Capability

Low
Category
Not specified by scanner
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.

Content

No source excerpt is available for this finding.