Back to skill

Security audit

MiniMax Search & Vision

Security checks for vulnerabilities and agentic risk

Overview

This MiniMax search and image skill appears purpose-aligned, but it asks users to run unpinned external tooling and passes broad local environment data to that tooling.

Install only if you are comfortable trusting the external mcporter and MiniMax MCP packages, and avoid using it with sensitive queries, screenshots, private images, or environments containing unrelated secrets until dependency versions are pinned, subprocess environment handling is narrowed, and local-file/privacy warnings are added.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T08 · Insecure Dependencies

Error
Location
SKILL.md:73
Finding

Unpinned Third-Party Packages Are Installed and Executed

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:73-84; README.md:64-75
Vulnerability Type: Supply-chain exposure through unpinned dependencies
Risk Level: High

Vulnerable Code

SKILL.md:73-84:

bash
npm install -g mcporter
bash
mcporter config add MiniMax \
    --command uvx \
    --args "minimax-coding-plan-mcp -y" \
    --env MINIMAX_API_KEY=$MINIMAX_API_KEY \
    --env MINIMAX_API_HOST=https://api.minimaxi.com \
    --scope home

The same unpinned installation and configuration instructions appear in README.md:64-75.

Technical Analysis

The installation instructions globally install the latest available mcporter npm package without a pinned version or integrity verification. The MCP configuration then uses uvx to retrieve and run minimax-coding-plan-mcp without a pinned version or package hash. The -y argument further indicates unattended execution.

Consequently, the code that executes is not fixed to the version reviewed in this audit. A compromised publisher account, malicious future release, dependency confusion event, or upstream package compromise could change the effective executable payload after the Skill has been reviewed.

Global npm installation also increases exposure because package installation scripts can execute with the installing user's privileges and affect commands available throughout that user's environment.

Attack Path

  1. An attacker compromises an upstream npm or Python package, its publisher account, or one of its transitive dependencies.
  2. The attacker publishes a malicious release under the package name used by the Skill.
  3. A user follows the documented unpinned installation instructions or invokes the uvx-configured MCP service.
  4. The package manager retrieves and executes the malicious release.
  5. The malicious package executes with the user's privileges and may access inherited environment variables, local files ...[truncated 555 chars]
Remediation
View remediation

Remediation Suggestions

  • Pin exact versions of both mcporter and minimax-coding-plan-mcp.
  • Verify package integrity using trusted lockfiles, hashes, signatures, or package-manager integrity metadata.
  • Review and pin all transitive dependencies.
  • Remove unattended execution flags where practical.
  • Install dependencies in a dedicated, unprivileged virtual environment rather than globally.
  • Use a controlled internal registry or verified package source for production deployments.
  • Document the verified publisher, package version, checksum, and upgrade-review procedure.
  • Re-audit dependency changes before updating pinned versions.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/web_search.py:34
Finding

External MCP Processes Inherit the Complete Parent Environment

Content
View full analysis

Vulnerability Details

File Location: scripts/web_search.py:34-56; scripts/understand_image.py:69-95
Vulnerability Type: Excessive privilege and secret exposure to external subprocesses
Risk Level: High

Vulnerable Code

scripts/web_search.py:34-56:

python
api_key = get_api_key()
api_host = get_api_host()

env = {
    **subprocess.os.environ,
    'MINIMAX_API_KEY': api_key,
    'MINIMAX_API_HOST': api_host,
}

cmd = [
    'mcporter-safe', 'call',
    'MiniMax.web_search',
    '--args', json.dumps({'query': query})
]

result = subprocess.run(
    cmd,
    capture_output=True,
    text=True,
    timeout=60,
    env=env,
    cwd=str(Path.home() / '.mcporter')
)

scripts/understand_image.py:69-95 repeats the same environment construction:

python
api_key = get_api_key()
api_host = get_api_host()

env = {
    **subprocess.os.environ,
    'MINIMAX_API_KEY': api_key,
    'MINIMAX_API_HOST': api_host,
}

args = {
    'prompt': prompt,
    'image_url': image_url
}

cmd = [
    'mcporter-safe', 'call',
    'MiniMax.understand_image',
    '--args', json.dumps(args)
]

result = subprocess.run(
    cmd,
    capture_output=True,
    text=True,
    timeout=120,
    env=env,
    cwd=str(Path.home() / '.mcporter')
)

Technical Analysis

Both subprocess wrappers copy the complete parent process environment into an externally installed executable. The invoked process therefore receives not only the MiniMax variables required for the operation, but also any unrelated secrets present in the runtime environment. Depending on the host, these may include cloud credentials, repository tokens, proxy credentials, CI/CD secrets, SSH agent configuration, database passwords, or API keys for unrelated services.

The command is resolved through PATH rather than through a verified absolute executable path. This increases the consequence ...[truncated 1422 chars]

Remediation
View remediation

Remediation Suggestions

  • Construct a minimal subprocess environment rather than copying subprocess.os.environ.
  • Include only variables strictly required by the MCP executable, such as MINIMAX_API_KEY, a fixed MINIMAX_API_HOST, and a controlled minimal PATH.
  • Resolve the executable once and invoke it using a verified absolute path.
  • Verify executable ownership, permissions, version, and integrity before invocation.
  • Reconcile the mcporter versus mcporter-safe naming mismatch and document the exact trusted binary.
  • Run the MCP process under a dedicated low-privilege account or sandbox with restricted filesystem and network access.
  • Allowlist the expected HTTPS MiniMax API host instead of accepting an arbitrary environment-controlled host.
  • Avoid placing unrelated service credentials in the environment of the parent Skill process.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/config.py:18
Finding

Credential File Is Read Without Ownership or Permission Validation

Content
View full analysis

Vulnerability Details

File Location: scripts/config.py:18-29; security claim in README.md:48-52
Vulnerability Type: Insecure credential-file handling
Risk Level: Medium

Vulnerable Code

scripts/config.py:18-29:

python
CREDENTIALS_DIR = Path.home() / ".openclaw" / "credentials"
CREDENTIAL_FILE = CREDENTIALS_DIR / "minimax_mcp.env"


def load_env_file(filepath: Path) -> dict:
    """Read environment variables from a .env file."""
    env_vars = {}
    if filepath.exists():
        with open(filepath, 'r') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#'):
                    if '=' in line:
                        key, value = line.split('=', 1)
                        env_vars[key.strip()] = value.strip()
    return env_vars

README.md:48-52 claims that credential permissions are checked:

markdown
## Security Notes

- ✅ API Key is read from an environment variable or credential file and is never hardcoded
- ✅ API Key is masked in output
- ✅ Credential file permission check (600)

No corresponding mode, ownership, regular-file, or symlink validation exists in the implementation.

Technical Analysis

Access to the dedicated MiniMax credential path is consistent with the Skill's functionality and is narrower than scanning a general credential directory. However, the loader trusts any filesystem object found at the configured path.

It does not verify that the credential file:

  • Is a regular file.
  • Is owned by the current user.
  • Has mode 0600 or stricter.
  • Is not a symbolic link.
  • Resides in a securely permissioned parent directory.

The documentation therefore provides a security assurance that the implementation does not enforce. A credential file that is group-readable or world-readable exposes the API key to other local users. A maliciously redirected file may als ...[truncated 1109 chars]

Remediation
View remediation

Remediation Suggestions

  • Use lstat() before opening the file and reject symbolic links.
  • Require the path to reference a regular file owned by the effective user.
  • Reject credential files with group or world permission bits; require mode 0600.
  • Validate that ~/.openclaw and its credentials directory are owned by the user and not writable by other principals.
  • Open the file using flags that prevent symlink traversal where supported, such as O_NOFOLLOW.
  • Create credential directories with mode 0700 and credential files with mode 0600.
  • Fail closed with a clear error if security checks fail.
  • Add automated tests covering permissive files, symlinks, incorrect ownership, and unsafe parent directories.
  • Keep the README security claim only after the checks are implemented.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/understand_image.py:24
Finding

Image Validation Accepts Arbitrary Local Files for External Processing

Content
View full analysis

Vulnerability Details

File Location: scripts/understand_image.py:24-45; delegation at scripts/understand_image.py:76-95
Vulnerability Type: Unrestricted local-file disclosure boundary
Risk Level: Medium

Vulnerable Code

scripts/understand_image.py:24-45:

python
def validate_image_url(image_url: str) -> bool:
    """
    Validate an image URL or local path.
    """
    if not image_url:
        return False

    # Local file
    if Path(image_url).is_file():
        # Check file size (maximum 20 MB)
        size_mb = Path(image_url).stat().st_size / (1024 * 1024)
        if size_mb > 20:
            raise ValueError(f"Image file is too large: {size_mb:.1f} MB (maximum 20 MB)")
        return True

    # HTTP/HTTPS URL
    if image_url.startswith(('http://', 'https://')):
        return True

    return False

scripts/understand_image.py:76-95 delegates the accepted path to the external MCP process:

python
args = {
    'prompt': prompt,
    'image_url': image_url
}

cmd = [
    'mcporter-safe', 'call',
    'MiniMax.understand_image',
    '--args', json.dumps(args)
]

result = subprocess.run(
    cmd,
    capture_output=True,
    text=True,
    timeout=120,
    env=env,
    cwd=str(Path.home() / '.mcporter')
)

Technical Analysis

The Skill documents support for JPEG, PNG, GIF, and WebP files, but local-file validation checks only whether the path exists as a file and whether its size is at most 20 MB. It does not inspect the extension, MIME type, magic bytes, decoded image structure, symlink status, or whether the path belongs to an approved directory.

Therefore, any readable local file below the size limit can pass validation and be handed to an external MCP process under the image_url parameter. Whether the downstream process uploads or otherwise reads the file depends on its implementation, but the wrapper establishes ...[truncated 1054 chars]

Remediation
View remediation

Remediation Suggestions

  • Require explicit user confirmation before processing any local file.
  • Restrict local inputs to user-approved directories or files selected through a controlled file-selection mechanism.
  • Resolve paths canonically and reject paths outside the approved scope.
  • Reject symlinks and non-regular files.
  • Validate image signatures and decode the image with a trusted image library before delegation.
  • Enforce the documented JPEG, PNG, GIF, and WebP formats using content-based checks rather than filename extensions alone.
  • Copy validated images into a private temporary directory using secure permissions and pass only that controlled copy to the MCP process.
  • Clearly disclose that local images may be transmitted to an external service.
  • Run the external image-analysis process in a sandbox that cannot read arbitrary local files.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向用户的“网络搜索和图片理解”技能,但给出的代码块只是配置模块,用于安全加载 MiniMax API Key 和 API Host,并提供脱敏显示。它没有发起网络请求、没有处理图片、没有调用 MiniMax MCP,也没有任何搜索或多模态分析逻辑。虽然凭据加载可能是该技能的支持性实现细节,但当前提供的代码块本身的实际行为与声明功能明显不一致,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

代码行为与描述存在明显不一致。描述声称该技能既可“网络搜索”又可“图片理解”,且支持通过 MCP 进行两类操作;但所给代码文件完全围绕 understand_image 展开,只验证图片输入并调用 MiniMax.understand_image,不包含搜索请求构造、搜索工具调用、检索结果处理或任何网络搜索逻辑。因此,代码未覆盖声明中的重要能力。其余行为如读取 API Key、调用外部 MCP、支持本地文件和 URL 图片,均与图片理解用途一致,属于支持性实现细节,不构成额外越权能力。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

描述中明确包含两项核心能力:网络搜索和图片理解/图片分析。但提供的代码块只实现了 web_search.py,功能集中于调用 MiniMax.web_search MCP 工具进行文本查询搜索,并处理超时、连接失败、输出解析等。代码没有接收图片输入、没有调用任何图像分析接口、也没有实现与图片理解相关的数据处理流程。因此,声明的能力范围大于代码实际行为,存在实质性描述不符。其余行为如读取配置、设置环境变量、调用外部 mcporter-safe 子进程,均可视为实现网络搜索的支撑细节,不构成额外未声明能力。

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/config.py (reported line 20)May include surrounding context.

python
def load_env_file(filepath: Path) -> dict:
    """从 .env 文件加载环境变量"""
    env_vars = {}
    if filepath.exists():
        with open(filepath, 'r') as f:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README advertises image understanding for HTTP URLs and local files but does not clearly warn that image contents may be transmitted to an external MiniMax service for processing. This can mislead users into sending sensitive local files, internal screenshots, or private images off-device without informed consent, increasing privacy and data leakage risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill describes capabilities that inherently require reading environment variables, accessing local credential files, and invoking shell-based setup commands, but it does not declare any explicit tool scope or permissions boundaries. This increases the chance that an agent may invoke sensitive capabilities without clear review or least-privilege controls, especially because the skill also references local file paths and command execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger phrases for activating web search are broad and match common user language such as '搜索...' or '在网上查找...'. Overbroad triggers can cause the skill to activate unexpectedly, sending user prompts or derived queries to an external service when the user did not intend to use this provider, which creates privacy and data-governance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill supports image analysis from HTTP/HTTPS URLs or local file paths, but it does not warn users that local files or image URLs may be transmitted to an external MiniMax service. In this context, that omission is meaningful because users may provide sensitive local images assuming analysis is local, leading to unintended exfiltration of private data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The examples encourage web search and image analysis against remote URLs and local files, but do not warn that prompts, URLs, and image contents may be transmitted to an external MiniMax-backed service. This can lead users to unknowingly send sensitive search terms, internal screenshots, or local file contents to a third party, especially because the documentation normalizes both public URLs and local-path analysis without privacy guidance.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documentation explicitly allows image_url to be a local file path, which creates a risk that the skill may access and transmit sensitive local files to an external MiniMax service. Without clear restrictions, consent requirements, or privacy warnings, users or downstream agents may unintentionally expose local data such as documents, screenshots, or system files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file’s natural-language documentation and runtime error/output strings are written exclusively in Chinese, and there is no indication that the skill is region-specific or that users can opt into another language. This can violate a language/locale policy when a skill imposes a specific language without offering choice or documenting a justified locale constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Natural-language strings throughout the file, including the module description, CLI help, logs, and errors, are exclusively in Chinese with no option for users to choose another language. This creates a language/locale policy issue because the skill imposes a fixed language rather than offering choice or documenting a justified locale constraint.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The manifest describes a MiniMax-based web search and image-understanding tool, which makes external service access expected. However, this implementation goes beyond direct API use by spawning a local command-line tool, setting inherited environment variables, and changing the working directory to a user home subdirectory. That local process-execution capability is not stated in the skill purpose and is broader than ordinary image-analysis behavior.

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/understand_image.py (reported line 95)May include surrounding context.

python
]
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The tool sends user-provided prompts and image locations, including local file paths, to an external MCP service without an explicit user-facing warning or consent step. In an image-understanding context this is materially risky because prompts, URLs, and possibly sensitive filesystem paths or image contents may leave the local environment unexpectedly.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstrings, CLI description, argument help, status logs, and error messages are all presented only in Chinese. This creates a language/locale policy issue because the skill does not provide any user opt-in, alternate locale, or justification that it is intended only for a Chinese-speaking or region-specific environment.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill performs a local external CLI execution and relies on ~/.mcporter state and inherited environment, which gives it broader host interaction than a narrowly described search helper would suggest. This expands the trust boundary to local binaries, PATH resolution, credential files, and working-directory state, increasing the chance of unintended command execution, binary hijacking, or leakage through local tool behavior.

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/web_search.py (reported line 51)May include surrounding context.

python
]
    
    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The docstring states use_mcp=False means 'use HTTP API' and describes web_search as returning search results, but the implementation has no HTTP path at all. On MCP failure it announces a fallback attempt and then raises NotImplementedError, directly contradicting the documented behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

Most user-facing instructions and examples in the file are presented only in Chinese. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale limitation is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The file presents all headings, comments, prompts, and CLI examples in Chinese only, which can constitute a language-policy issue when no user opt-in or justification is provided. The policy specifically calls for flagging skills that force a specific language or locale without offering choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The web search feature sends user queries to an external provider, but the documentation does not warn that entered data leaves the local environment. This can lead to unintentional disclosure of sensitive prompts, internal project names, credentials pasted by mistake, or other confidential information through search requests.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The only natural-language content in this file is a Chinese-language module docstring naming the skill. Under the policy, forcing a specific language without user opt-in or documented locale justification can be a natural-language policy issue, and this file provides neither.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The comment says credentials are read automatically from a credentials file, but the code explicitly injects MINIMAX_API_KEY and MINIMAX_API_HOST into the subprocess environment. That discrepancy can mislead reviewers and operators about where secrets flow, increasing the risk of accidental credential exposure through child-process inspection, logging, crash dumps, or untrusted wrapper binaries.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.