Back to skill

Security audit

MC Ecosystem Adaptation Engineer

Security checks for vulnerabilities and agentic risk

Overview

The skill is a broad Minecraft mod manager, but it mixes file-changing features, device tracking, payment flows, and poorly disclosed network behavior in ways users should review carefully before installing.

Install only if you are comfortable with a broad tool that can modify mod/save files, generate and expose a persistent machine ID, create payment pages, and contact network services. Avoid restoring untrusted synchronized backups or processing untrusted JAR/ZIP files until archive extraction is fixed, and review the payment/auth behavior because the privacy and feature documentation is inconsistent.

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 (3)

T09 · Insecure Skill Coding Practices

Warning
Location
core/i18n.py:184
Finding
Automatic Disclosure of Public IP Address to Third-Party Geolocation Services<![CDATA[ ## Vulnerability Details **File Location**: `core/i18n.py:184-207`, `core/i18n.py:268-278`, and `core/i18n.py:592` **Vulnerability Type**: Automatic third-party data disclosure and insecure plaintext HTTP communication **Risk Level**: Medium ### Vulnerable Code ```python _IP_GEO_APIS = [ { "url": "http://ip-api.com/json/?fields=status,countryCode,country,regionName,city", "timeout": 5, "parse": lambda r: (r.get("countryCode") or "").upper() if r.get("status") == "success" else "", }, { "url": "https://ipinfo.io/json", "timeout": 5, "parse": lambda r: (r.get("country") or "").upper(), }, { "url": "https://api.myip.com", "timeout": 5, "parse": lambda r: (r.get("cc") or "").upper(), }, { "url": "https://freegeoip.app/json/", "timeout": 8, "parse": lambda r: (r.get("country_code") or r.get("countryCode") or "").upper(), }, ] ``` ```python for api_cfg in _IP_GEO_APIS: try: resp = requests.get( api_cfg["url"], timeout=api_cfg.get("timeout", 5), headers={ "User-Agent": "MC-Skill-V1/1.0 (i18n geo detection)", "Accept": "application/json", }, ) if resp.status_code != 200: continue data = resp.json() cc = api_cfg["parse"](data) ``` The behavior is enabled automatically at module import: ```python # Module-load initialization with automatic detection enabled init_language(auto_detect=True) ``` ### Technical Analysis The internationalization module performs public-IP geolocation automatically when it is imported and no explicit language preference is available. `main.py` imports `core.i18n` during normal startup, so this network behavior can occur without the user invoking a network-dependent feature. Every contacted provider inherently receives the user's public IP address, request ti ...[truncated 2047 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable IP-based geolocation by default: ```python init_language(auto_detect=False) ``` 2. Use explicit language selection, a saved user preference, or the operating-system locale as the default detection mechanism. 3. Require informed, affirmative user consent before contacting any geolocation provider. 4. Remove the plaintext `http://ip-api.com` endpoint. If geolocation remains available, use HTTPS exclusively. 5. Use a single documented provider rather than disclosing the user's IP to multiple fallback services. 6. Add a configuration option such as `ENABLE_IP_GEOLOCATION = False`, without executing network requests merely by importing a module. 7. Document the provider, transmitted metadata, purpose, caching period, and opt-out procedure in the privacy notice. 8. Avoid performing network activity at import time; invoke optional geolocation only from an explicit initialization or user-interface action. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
utils/jar_utils.py:54
Finding
Path Traversal During JAR and ZIP Extraction<![CDATA[ ## Vulnerability Details **File Location**: `utils/jar_utils.py:54-55` **Affected Callers**: `core/jar_parser.py:613`, `core/mixin_scanner.py:165`, `core/repacker.py:422`, and `core/translator.py:301` **Vulnerability Type**: Zip Slip arbitrary file write **Risk Level**: High ### Vulnerable Code ```python try: with zipfile.ZipFile(jar_path, "r") as zf: zf.extractall(dest_dir) logger.info(f"JAR解压成功: {jar_path.name} -> {dest_dir}") except zipfile.BadZipFile as e: logger.error(f"JAR文件损坏: {jar_path} - {e}") raise except Exception as e: logger.error(f"JAR解压失败: {jar_path} - {e}") raise ``` ### Technical Analysis The shared `extract_jar()` utility passes all archive members directly to `ZipFile.extractall()` without validating their paths. A ZIP or JAR entry can contain traversal components such as `../../target`, an absolute path, or platform-specific path constructions. If the resolved destination of such an entry falls outside `dest_dir`, extraction can overwrite files elsewhere on the filesystem with the privileges of the user running the Skill. Merely restricting the input extension to `.jar` or `.zip` does not make the archive trustworthy. The vulnerable utility is reachable through several features designed to process externally obtained or attacker-supplied Minecraft mod JARs. This makes malicious mod files a realistic delivery mechanism. Archive links and special entries are not explicitly rejected either. Safe extraction should account for traversal paths, absolute paths, symbolic links, and platform-specific separator behavior. ### Attack Path 1. An attacker creates a JAR containing a member such as: ```text ../../../../home/user/.config/example/startup.py ``` or an equivalent path targeting a writable application or configuration file. 2. The attacker publishes or sends the JAR as a Minecraft mod. 3. The user supplies the JAR to the parser, Mixin scanner, repacker, or translator. 4. The selecte ...[truncated 1206 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate every archive member before writing it: ```python def safe_extract(zf: zipfile.ZipFile, dest_dir: Path) -> None: root = dest_dir.resolve() for info in zf.infolist(): member = Path(info.filename) if member.is_absolute() or ".." in member.parts: raise ValueError(f"Unsafe archive path: {info.filename}") target = (root / member).resolve() try: target.relative_to(root) except ValueError: raise ValueError(f"Archive entry escapes destination: {info.filename}") # Reject Unix symbolic links stored in ZIP metadata. mode = info.external_attr >> 16 if (mode & 0o170000) == 0o120000: raise ValueError(f"Symbolic links are not allowed: {info.filename}") for info in zf.infolist(): zf.extract(info, root) ``` Additional hardening should include: 1. Reject absolute, drive-qualified, UNC, traversal, symbolic-link, and special-file entries. 2. Normalize both `/` and `\` separators when archives may be processed across platforms. 3. Limit the number of entries, total uncompressed size, individual entry size, and compression ratio to mitigate archive bombs. 4. Extract into a newly created private temporary directory. 5. Apply the safe extractor consistently to every JAR-processing workflow. 6. Add regression tests for `../`, absolute paths, Windows drive paths, UNC paths, symlinks, and nested traversal. 7. Do not rely solely on archive suffixes or MIME types as trust controls. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
core/save_sync.py:549
Finding
Path Traversal During Cloud-Synchronized Save Restoration<![CDATA[ ## Vulnerability Details **File Location**: `core/save_sync.py:549-554` **Vulnerability Type**: Zip Slip arbitrary file write through synchronized backup archives **Risk Level**: High ### Vulnerable Code ```python # Extract backup restored_files = 0 try: with zipfile.ZipFile(selected, "r") as zf: for name in zf.namelist(): if not name.endswith("/"): zf.extract(name, saves_dir) restored_files += 1 except zipfile.BadZipFile as e: return config.make_result( status="error", feature="F6", input_summary={"action": "restore", "backup_file": str(selected)}, result={"error": f"备份文件损坏: {e}"}, errors=[f"备份文件损坏: {e}"], ) ``` ### Technical Analysis The save restoration workflow extracts every non-directory member from the selected ZIP directly into `saves_dir`. The code does not verify that the resolved output path remains within that directory. Checking only whether a filename ends with `/` does not prevent traversal. An archive member such as `../../../target` is treated as a normal file and passed to `ZipFile.extract()`. The input is selected from a synchronized backup directory. Consequently, an attacker who can replace, inject, or tamper with a backup in that directory can turn the restore operation into an arbitrary file-write primitive. Possible sources include a compromised cloud account, an unsafe shared synchronization folder, another device with access to the same account, or a malicious archive introduced locally. There is no cryptographic authenticity or integrity check proving that a backup was created by this installation. ### Attack Path 1. The attacker obtains write access to the user's synchronized backup directory or cloud account. 2. The attacker creates a backup with the expected filename pattern and includes a traversal entry targeting a writable file outside the Minecraft save directory. 3. The malicious file is synchronized to the ...[truncated 1049 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace direct `ZipFile.extract()` calls with the same centralized safe extraction routine used for JAR files. 2. Resolve each output path and require it to remain beneath `saves_dir`. 3. Reject absolute paths, parent-directory traversal, drive-qualified paths, UNC paths, links, and special files. 4. Authenticate backups before restoration. For example, store an HMAC or digital signature generated with a key unavailable to the cloud provider and verify it locally. 5. Display the selected archive and require confirmation when it was not generated by the current installation. 6. Extract into a private staging directory first, validate the complete structure, and only then copy expected Minecraft save files into `saves_dir`. 7. Restrict restored content to expected save layouts rather than accepting arbitrary archive paths. 8. Enforce archive size, entry-count, and compression-ratio limits to prevent disk-exhaustion attacks. 9. Preserve an existing save backup before replacing files and provide rollback after validation failure. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
Findings (128)

Tainted flow: 'req' from os.environ.get (line 771, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
        )

        with urlopen(req, timeout=AUTH_SERVER_TIMEOUT) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            return result
Confidence
90% confidence
Finding
Online license verification posts the machine ID to a URL controlled by MC_SKILL_SERVER_URL. If that environment variable is tampered with, the client will send identifying data and trust responses from an attacker-controlled endpoint, undermining license validation and exposing device-linked information.

Tainted flow: 'req' from os.environ.get (line 771, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="POST",
    )
    
    with urlopen(req, timeout=AUTH_SERVER_TIMEOUT) as resp:
        return json.loads(resp.read().decode("utf-8"))
Confidence
92% confidence
Finding
The destination URL is derived from the MC_SKILL_SERVER_URL environment variable and then used for signed telemetry/reporting requests. This allows an attacker who can influence the process environment to redirect sensitive device identifiers, usage records, and signed requests to an arbitrary server, enabling data exfiltration and possible replay or abuse of the shared-client signing scheme.

Ae1

High
Category
analysis-evasion
Content
icon: assets/icon-market.jpg
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
icon_local: assets/icon-local.jpg
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The privacy section contains materially conflicting claims: one part states no data is transmitted externally by default, while the following section says mandatory online verification and periodic usage reporting are enabled by default. This can mislead users and reviewers about actual network behavior, undermining informed consent and masking device fingerprinting and telemetry tied to a machine identifier.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
y": _PAYMENT_ASSETS / "unionpay_qr.png",
    "digital": _PAYMENT_ASSETS / "digital_yuan_qr.png",
    "douyin": _PAYMENT_ASSETS / "douyin_pay_qr.png",
}

# === 主支付渠道配置 ===
_PRI_PAYMENT_CHANNELS = {
    "wechat_pay": {
        "name": "微信支付",
        "name_en": "WeChat Pay",
        "icon": "💬",
        "color": "#07C160",
        "bg_color": "#e8f5e9",
        "description": "请打开微信 APP 扫码付款",
        "description_en": "Open WeChat App to scan QR code",
    },
    "alipay": {
        "name": "支付宝",
        "name_en": "Alipay",
        "icon": "💙",
        "color": "#1677FF",
        "bg_color": "#e3f2fd",
        "description": "请打开支付宝 APP 扫码付款",
        "description_en": "Open Alipay App to scan QR code",
    },
    "paypal": {
        "name": "PayPal/外币",
        "name_en": "PayPal / Foreign Currency",
        "icon": "🌍",
        "color": "#003087",
        "bg_color": "#e3f2fd
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Self-Modification

High
Category
Rogue Agent
Content
"warning.experimental": "This is an experimental feature",
  "warning.config_recommended": "Using config file is recommended for batch operations",
  "prompt.confirm_continue": "Continue?",
  "prompt.confirm_overwrite": "Overwrite existing files?",
  "prompt.confirm_delete": "Delete selected items?",
  "prompt.confirm_exit": "Exit without saving?",
  "prompt.input_required": "Input is required",
Confidence
85% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The README advertises cloud save synchronization but gives no disclosure about what user data is uploaded, where it is stored, how it is protected, or whether third parties are involved. In a gaming tool that handles user save data, this can mislead users into transmitting personal or gameplay data without informed consent, increasing privacy and data-loss risk if the backend is insecure or misconfigured.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The README introduces online payment, membership, and admin-console features without explaining how payment data, account identifiers, order records, and authorization data are processed or protected. Because the skill also mentions a backend, machine binding, admin tokens, and order tracking, the missing disclosure materially increases the risk of unsafe handling of financial and account data and can normalize users entering sensitive information into an inadequately described system.

Vague Triggers

Medium
Confidence
88% confidence
Finding
The manifest describes a very broad, multi-purpose skill covering local file access, file modification, networked downloads, save synchronization, authorization, payments, admin functions, and business reporting under a single umbrella description. That breadth increases the chance of over-activation, user confusion, and unintended invocation of sensitive capabilities, especially because the description reads like a general all-in-one operator rather than a narrowly scoped game utility.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The manifest includes sensitive behaviors—save backup/restore, local machine fingerprinting, usage tracking, payment flows, admin dashboard, and automated business reports—without strong, prominent warnings about privacy implications, external services, financial risk, or system-side effects. Even though some declarations mention local-only storage or optional transmission, the user-facing description emphasizes features and commercialization rather than consent boundaries, which can lead users to trigger risky actions without informed understanding.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The 'one-click mod upgrade' feature implies automatic modification of installed mod files to remediate crashes, yet the document does not prominently warn about file replacement, compatibility regressions, or the need for backup/confirmation. In a game-mod environment, automated upgrades can break worlds, introduce incompatible versions, or irreversibly alter a user's setup.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill claims mandatory auth verification and periodic usage reporting, but the usage instructions do not present a prominent consent or warning flow before execution. Because the reported data includes a stable machine identifier and usage activity, users may unknowingly disclose device-linked telemetry simply by using ordinary commands.

Intent-Code Divergence

Medium
Confidence
91% confidence
Finding
The file claims v1.0.4 adds complete commercialization support including an online payment system, but the payment guide section says payment prompts are not shown because ENABLE_PAYMENT is false in V1.0.1. This is an active contradiction about whether payment-related behavior is available in the current version.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The save restore feature writes backup data back into the local saves directory, but the documentation does not clearly warn that restore may overwrite existing world data. Given Minecraft save files are user-generated and often irreplaceable, unclear restore semantics can lead to permanent data loss through accidental overwrite.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This code file contains natural-language instructions and documentation primarily in Chinese, beginning with the module docstring and continuing through comments and docstrings. The policy explicitly calls for flagging language/locale constraints when a specific language is imposed without user opt-in or a documented justification.

External Transmission

Medium
Category
Data Exfiltration
Content
MODRINTH_RATE_LIMIT = 300  # 每分钟最大请求数

    # CurseForge API (需要API Key)
    CURSEFORGE_BASE = "https://api.curseforge.com/v1"
    CURSEFORGE_GAME_ID = 432  # Minecraft的gameId
    CURSEFORGE_CLASS_MOD = 6  # Mod分类
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Intent-Code Divergence

Medium
Confidence
97% confidence
Finding
The module claims to perform 'machine ID + server signature' dual verification, but the implementation only posts a machine identifier and trusts whatever JSON comes back. Without cryptographic verification of the server response, any party able to spoof or tamper with the response path can grant authorization or alter entitlement data, especially since the transport is plain HTTP to localhost.

External Transmission

Medium
Category
Data Exfiltration
Content
# 1. 尝试在线查询
    try:
        resp = requests.post(
            f"{SERVER_URL}/api/auth/quick-check",
            json={"machine_id": machine_id},
            timeout=5
Confidence
93% confidence
Finding
The module sends a machine identifier to an external service endpoint as part of authorization, which is sensitive telemetry in this context. The danger is amplified by the fact that the endpoint uses HTTP rather than HTTPS, so local proxies, malware, or network intermediaries may observe or tamper with the request/response, potentially affecting both privacy and authorization integrity.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The code transmits a stable machine-derived identifier to the server automatically, with no user notice, consent flow, or minimization controls. Persistent identifiers enable device tracking and user correlation across sessions; in this skill context, the risk is elevated because authorization checks happen silently during normal operation.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The background polling thread performs recurring network authorization checks every five minutes without any user-facing warning or control. This creates continuous metadata leakage and ongoing device tracking, and can also surprise operators in environments where unsolicited network activity is sensitive or prohibited.

Natural-Language Policy Violations

Medium
Confidence
81% confidence
Finding
Multiple user-facing docstrings and printed notices in this file are written directly in Chinese, including onboarding and authorization messages. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy issue unless the locale restriction is explicitly justified or a language choice is offered.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The module header states '强制联网验证 - 每次使用Skill都验证授权状态', which implies online verification is always enforced. In code, AUTH_SERVER_URL defaults to an empty string, causing _force_online_verify() to succeed in offline mode, and even when a server is configured, network failures can downgrade to offline use for free-period or locally licensed users.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
import subprocess
            import sys
            if sys.platform == "win32":
                subprocess.run("clip", input=machine_id, capture_output=True, text=True)
                print("  ✅ 机器码已自动复制到剪贴板\n")
        except Exception:
            print("  💡 请手动复制上面的机器码\n")
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
import subprocess
            import sys
            if sys.platform == "win32":
                subprocess.run("clip", input=machine_id, capture_output=True, text=True)
                print("  ✅ 机器码已自动复制到剪贴板\n")
        except Exception:
            print("  💡 请手动复制上面的机器码\n")
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.