Back to skill

Security audit

MiniMax DOCX Pro

Security checks for vulnerabilities and agentic risk

Overview

This Word document skill mostly matches its stated purpose, but it can automatically download and run a .NET installer and modify the user's local .NET runtime without clear top-level disclosure.

Review before installing. Use this only where automatic network installation and persistent writes to ~/.dotnet are acceptable, or preinstall .NET and disable/remove the auto-provisioning path. Avoid running its audit or map-apply commands on untrusted DOCX files in shared workers unless archive extraction is sandboxed or resource-limited.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T03 · Remote Payload Retrieval and Execution

Error
Location
docx_engine.py:209
Finding
Automatic Retrieval and Execution of an Unpinned Remote .NET Installer<![CDATA[ ## Vulnerability Details **File Location**: `docx_engine.py`, lines 209-265 **Vulnerability Type**: Unverified remote code retrieval and execution **Risk Level**: High ### Vulnerable Code ```python def provision_dotnet() -> Optional[Path]: """Download and install .NET SDK automatically. Returns: Path to the installed binary, or None on failure. """ os_type = platform.system() channel = required_dotnet_channel() print(" Acquiring .NET SDK...") try: if os_type == "Windows": installer_url = "https://dot.net/v1/dotnet-install.ps1" target_dir = Path.home() / ".dotnet" powershell_script = f""" $ErrorActionPreference = 'Stop' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $installer = Invoke-WebRequest -Uri '{installer_url}' -UseBasicParsing $execution = [scriptblock]::Create($installer.Content) & $execution -Channel {channel} -InstallDir '{target_dir}' """ subprocess.run( ["powershell", "-Command", powershell_script], capture_output=True, text=True, timeout=300 ) binary = target_dir / "dotnet.exe" else: installer_url = "https://dot.net/v1/dotnet-install.sh" target_dir = Path.home() / ".dotnet" installer_path = Path(tempfile.gettempdir()) / "dotnet-bootstrap.sh" subprocess.run( ["curl", "-sSL", installer_url, "-o", str(installer_path)], check=True, timeout=60 ) installer_path.chmod(0o755) subprocess.run( [str(installer_path), "--channel", channel, "--install-dir", str(target_dir)], check=True, timeout=300 ) binary = target_dir / "dotnet" if binary.exists(): verify = subprocess.run([str(binary), "--version"] ...[truncated 3247 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic download-and-execute behavior from normal document operations. 2. Treat a missing or incompatible runtime as a diagnostic error and provide manual installation instructions. 3. If automated provisioning is essential: - Download a versioned, immutable artifact rather than a mutable bootstrap URL. - Pin the exact .NET SDK version. - Verify a hardcoded SHA-256 or stronger digest before execution. - Validate an official digital signature where supported. - Abort on any integrity or signature mismatch. 4. Require explicit, informed user approval before making network requests or executing an installer. 5. Run provisioning in a sandbox with restricted filesystem access, no document access, and no inherited secrets. 6. On Unix-like systems, use a securely created private temporary directory and an unpredictable filename rather than a fixed path in the shared temporary directory. 7. Do not automatically delete an installation merely because the runtime probe reports corruption. Quarantine it or request user intervention. 8. Log the exact URL, resolved SDK version, expected digest, actual digest, and verification result for auditability. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
docx_engine.py:1383
Finding
Unbounded Extraction of Untrusted DOCX Archives Enables Resource Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `docx_engine.py`, lines 1383-1386 **Vulnerability Type**: Unrestricted archive extraction **Risk Level**: Medium ### Vulnerable Code ```python with tempfile.TemporaryDirectory(prefix="docx_map_apply_") as tmp: extract_dir = Path(tmp) / "unpacked" with zipfile.ZipFile(input_path, "r") as archive: archive.extractall(extract_dir) ``` ### Technical Analysis A DOCX file is a ZIP archive and must be treated as untrusted structured input. The `map-apply` operation extracts every archive member before checking whether the expected `word/document.xml` part exists. There are no limits on: - Number of archive entries - Total declared uncompressed size - Compression ratio - Per-entry size - Extraction time - Available disk space consumed - Member types or allowed DOCX paths An attacker can therefore provide a highly compressed DOCX archive whose expanded contents are much larger than the uploaded file. Extraction may consume temporary-storage capacity, memory, CPU time, or inode quotas before semantic validation begins. This is a ZIP-bomb denial-of-service condition. The implementation also relies entirely on the runtime library's filename normalization rather than explicitly rejecting absolute paths, parent-directory components, duplicate normalized names, or unusual member types. Explicit validation is appropriate because archive-handling behavior can differ across runtime versions and platforms. ### Attack Path 1. An attacker supplies a file named with a `.docx` extension containing a malicious ZIP archive. 2. The archive includes either extremely large compressed members, many small members, or entries with extreme compression ratios. 3. A user or automated workflow invokes: ```bash python docx_engine.py map-apply malicious.docx mapping.json output.docx ``` 4. `archive.extractall(extract_dir)` expands every member without inspecting archive metadata or enforcing quotas. 5. Tempora ...[truncated 780 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Inspect every `ZipInfo` object before extraction. 2. Reject archives exceeding conservative limits for: - Entry count - Per-entry uncompressed size - Cumulative uncompressed size - Compression ratio - Filename length and path depth 3. Reject absolute paths, drive-qualified paths, `..` components, NUL characters, duplicate normalized paths, and unsupported member types. 4. Permit only paths expected in an OOXML package, or at minimum ensure every resolved destination remains beneath the private extraction directory. 5. Extract entries individually using bounded streaming rather than calling `extractall()`. 6. Monitor actual bytes written because ZIP metadata cannot always be trusted as the sole enforcement mechanism. 7. Apply process-level CPU, memory, execution-time, and filesystem quotas when handling user-provided documents. 8. Check available disk capacity before extraction and clean up immediately on validation failure. 9. Apply the same hardened extraction helper to every DOCX extraction path, including the validation pipeline, so security controls remain consistent. 10. Add regression tests using oversized entries, excessive entry counts, high compression ratios, absolute paths, traversal components, and duplicate normalized names. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (45)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
Repairing and normalizing existing WordprocessingML structures is a materially different capability from simple document generation and should be disclosed. Structural mutation of user-supplied documents can alter content fidelity, strip artifacts, or unexpectedly rewrite files, which is more sensitive in enterprise document workflows.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
This section performs network-backed installation by downloading installer scripts and then executing them. In a document-generation skill, that is especially dangerous because it creates an unnecessary remote code execution and supply-chain attack surface unrelated to processing DOCX content itself.

Env Variable Harvesting

High
Category
Data Exfiltration
Content
print("  + Compiled")

    print(">> Generating...")
    run_env = os.environ.copy()
    run_env.setdefault("DOTNET_ROLL_FORWARD", "LatestMajor")
    proc = subprocess.run(
        [
Confidence
60% confidence
Finding
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill exposes operationally sensitive capabilities through documented shell execution, file read/write, and environment access, but does not declare any explicit tool scope or permission boundaries. In an agent setting, this increases the chance of over-broad execution and makes it harder for a policy layer to constrain what the skill may do.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return ("absent", None, None)

    try:
        proc = subprocess.run(
            [str(binary), "--version"],
            capture_output=True, text=True, timeout=10
        )
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The skill's declared purpose is document generation, but it silently expands scope into runtime acquisition and installation. That hidden behavior is security-relevant because users invoking a document tool may not expect software installation and remote code retrieval, increasing the chance of unsafe execution in sensitive environments.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
$execution = [scriptblock]::Create($installer.Content)
            & $execution -Channel {channel} -InstallDir '{target_dir}'
            """
            subprocess.run(
                ["powershell", "-Command", powershell_script],
                capture_output=True, text=True, timeout=300
            )
Confidence
97% confidence
Finding
This code downloads PowerShell content from the internet and immediately executes it in-process without signature verification, pinning, or explicit user confirmation at the moment of execution. That creates a supply-chain remote code execution path: if the network path, upstream host, or returned content is tampered with, arbitrary code runs with the user's privileges.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
target_dir = Path.home() / ".dotnet"

            installer_path = Path(tempfile.gettempdir()) / "dotnet-bootstrap.sh"
            subprocess.run(
                ["curl", "-sSL", installer_url, "-o", str(installer_path)],
                check=True, timeout=60
            )
Confidence
95% confidence
Finding
This command retrieves an installer script over the network into a temporary file. On its own it is a download step, but in this workflow it directly feeds an execution path, making the system dependent on remote content integrity and exposing users to supply-chain compromise.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
check=True, timeout=60
            )
            installer_path.chmod(0o755)
            subprocess.run(
                [str(installer_path), "--channel", channel, "--install-dir", str(target_dir)],
                check=True, timeout=300
            )
Confidence
97% confidence
Finding
After downloading a script to `/tmp`, the code marks it executable and runs it automatically. This is dangerous because it executes untrusted network-fetched code with no integrity validation, and temporary directories can also introduce local tampering concerns in some environments.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
binary = target_dir / "dotnet"

        if binary.exists():
            verify = subprocess.run([str(binary), "--version"], capture_output=True, text=True)
            if verify.returncode == 0:
                print(f"  + Provisioned: {verify.stdout.strip()}")
                return binary
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
`guarantee_dotnet()` can automatically trigger download/install behavior and even delete `~/.dotnet` in the corrupted case, all without an explicit confirmation prompt at the point of action. That is unsafe operationally and security-wise because merely running a normal workflow command can lead to remote code execution and destructive local changes.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
pandoc_binary = shutil.which("pandoc")
    if pandoc_binary:
        try:
            proc = subprocess.run(["pandoc", "--version"], capture_output=True, text=True, timeout=5)
            ver = proc.stdout.split("\n")[0].split()[-1] if proc.returncode == 0 else "?"
            inventory["pandoc"] = ("available", ver)
        except Exception:
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Content
for pkg in ["playwright", "matplotlib", "PIL"]:
        try:
            __import__(pkg if pkg != "PIL" else "PIL.Image")
            inventory[pkg] = ("available", None)
        except ImportError:
            inventory[pkg] = ("optional", None)
Confidence
75% confidence
Finding
Dynamic __import__() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Static analysis

No suspicious patterns detected.