Back to skill

Security audit

Hailuo Gyh

Security checks for vulnerabilities and agentic risk

Overview

This MiniMax video-generation skill is coherent and user-directed, but users should notice that prompts and image references go to MiniMax and the API-key wording is inconsistent.

Install only if you are comfortable sending your prompts and supplied image or face-reference URLs to MiniMax. Set your own MINIMAX_API_KEY rather than expecting an embedded key, avoid sensitive or third-party face images without permission, and prefer installing dependencies in an isolated environment.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:18
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, line 18
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable Code

bash
pip3 install requests

Technical Analysis

The installation instructions direct users to install requests without pinning a reviewed version, verifying package hashes, using a lockfile, or specifying a trusted package index. Consequently, the package and its transitive dependencies remain mutable and are selected from the user's configured Python package repository at installation time.

This creates a supply-chain exposure: compromise of the package repository, a dependency, the user's package-index configuration, or a future selected release could cause unreviewed code to be installed. Python packages may execute build or installation logic, so a malicious dependency can potentially run code during installation.

The audit found no evidence that the current requests package is malicious. The issue is the unsafe, non-reproducible dependency installation procedure.

Attack Path

  1. An attacker compromises a selected package release, one of its transitive dependencies, or a package index configured on the victim's system.
  2. A user follows the documented command:
    bash
    pip3 install requests
    
  3. pip resolves packages dynamically without enforcing reviewed versions or cryptographic hashes.
  4. The compromised package is downloaded and installed.
  5. Malicious build or installation code executes with the privileges of the user running pip; malicious runtime code could subsequently execute when video_gen.py imports the package.

Impact Assessment

Successful exploitation could provide arbitrary code execution under the account that performs the installation or runs the affected package. The resulting access would generally include that user's readable files, environment variables, network permissions, and writable resources. If installation is pe ...[truncated 121 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a dependency file containing reviewed, exact versions rather than installing an unconstrained package.
  2. Generate and record cryptographic hashes for every direct and transitive dependency.
  3. Install with hash enforcement, for example:
    bash
    python3 -m pip install --require-hashes -r requirements.txt
    
  4. Use an isolated virtual environment and a trusted, explicitly configured package index.
  5. Review and update pinned dependencies through a controlled process that includes vulnerability scanning and regression testing.
  6. Keep the lockfile or fully resolved requirements file under version control to ensure reproducible installations.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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
Findings (20)

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/video_gen.py (reported line 32)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/video_gen.py (reported line 48)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/video_gen.py (reported line 65)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/video_gen.py (reported line 86)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/video_gen.py (reported line 102)May include surrounding context.

python
while True:
        time.sleep(10)
        response = requests.get(url, headers=HEADERS, params=params)
        response.raise_for_status()
        response_json = response.json()
        status = response_json["status"]

Tainted flow: 'HEADERS' from os.environ.get (line 19, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/video_gen.py (reported line 118)May include surrounding context.

python
while True:
        time.sleep(10)
        response = requests.get(url, headers=HEADERS, params=params)
        response.raise_for_status()
        response_json = response.json()
        status = response_json["status"]

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill invokes a Python script that uses both environment variables and outbound network access to call the MiniMax API, but the manifest does not declare any corresponding tool scope or permissions. This creates a transparency and policy-enforcement gap: users and hosting platforms cannot clearly assess or constrain the skill's ability to read secrets and transmit data externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill supports uploading user-provided images, including face photos for the 'subject' mode, to a third-party API but does not provide any privacy warning or consent guidance. Because face images are highly sensitive biometric data, users may unknowingly transmit personal media and prompts to an external service without understanding retention, processing, or jurisdictional risks.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The metadata claims the API key is embedded in the skill ('API Key 已内置'), which contradicts the stated requirement to configure MINIMAX_API_KEY externally. Advertising or relying on an embedded credential strongly suggests hardcoded secret distribution, creating a serious risk of credential leakage, unauthorized API use, and inability to rotate access safely if the skill is shared or published.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description is written entirely in Chinese and labels the skill as a dedicated personal version ("龚云荷专属版本") without indicating any language choice or opt-in. This can violate a language/locale policy when the skill appears in a broader catalog or is used by users who have not selected Chinese.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

The top-level documentation states "API Key 已内置,无需配置环境变量", which directly contradicts the implementation that reads MINIMAX_API_KEY from the environment and terminates when it is not set. This is an active intent/documentation mismatch, not merely omitted detail.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/video_gen.py (reported line 32)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/video_gen.py (reported line 48)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/video_gen.py (reported line 65)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/video_gen.py (reported line 86)May include surrounding context.

python
"duration": duration,
        "resolution": resolution,
    }
    response = requests.post(url, headers=HEADERS, json=payload)
    response.raise_for_status()
    task_id = response.json()["task_id"]
    return task_id

Tainted flow: 'params' from requests.post (line 95, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/video_gen.py (reported line 102)May include surrounding context.

python
while True:
        time.sleep(10)
        response = requests.get(url, headers=HEADERS, params=params)
        response.raise_for_status()
        response_json = response.json()
        status = response_json["status"]

Tainted flow: 'params' from requests.post (line 95, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/video_gen.py (reported line 118)May include surrounding context.

python
while True:
        time.sleep(10)
        response = requests.get(url, headers=HEADERS, params=params)
        response.raise_for_status()
        response_json = response.json()
        status = response_json["status"]

Tainted flow: 'download_url' from requests.get (line 120, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
90% confidence
Finding

The script blindly follows a download_url supplied by the API response and performs a second GET without validating the destination host or scheme. If the upstream service is compromised, misconfigured, or returns attacker-controlled URLs, this can turn the client into an SSRF-like requester or cause downloads from unexpected internal or malicious locations.

Content

Scanner excerpt · scripts/video_gen.py (reported line 124)May include surrounding context.

python
print(f"📥 正在下载视频至 {output_path}...")
    with open(output_path, "wb") as f:
        video_response = requests.get(download_url)
        video_response.raise_for_status()
        f.write(video_response.content)
    print(f"✅ 视频已保存: {output_path} ({os.path.getsize(output_path) / 1024:.0f} KB)")

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The argument help says text(图生视频) and image(首帧图片+提示词), but the code implements text as pure text-to-video and image as image-to-video. This is a direct contradiction between inline documentation and behavior that could mislead users about what data is sent to the API.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

Line L134 says the video prompt is 'recommended in English' (建议英文), which is a natural-language locale preference embedded in the tool behavior. Under the policy, forcing or steering toward a specific language without user opt-in can be a locale-policy issue, and there is no alternative language choice or justification documented here.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.