Back to skill

Security audit

meituan-coupon-order-assistant

Security checks across malware telemetry and agentic risk

Overview

The skill partly fits a Meituan ordering assistant, but it also includes under-disclosed background updating, device fingerprinting, token/location persistence, and broad automatic triggers.

Review this skill carefully before installing. It may require Meituan account login and location access, can retain local auth/location/device state, and includes a background vendor component that can update and run code outside the packaged skill. Only use it if you trust the publisher and are comfortable with local device profiling and explicit confirmation before any order or payment action.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • 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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (87)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 清除 pt-passport CLI 本地缓存的 Token
    cli_cleared = False
    try:
        result = subprocess.run(
            [PT_PASSPORT_BIN, "logout", "--client_id", "578aafab312b44f1b76b0529b06bb0c6"],
            capture_output=True, text=True, timeout=10
        )
Confidence
70% confidence
Finding
result = subprocess.run( [PT_PASSPORT_BIN, "logout", "--client_id", "578aafab312b44f1b76b0529b06bb0c6"], capture_output=True, text=True, timeout=10 )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# 同时清除 pt-passport CLI 缓存
    try:
        subprocess.run(
            [PT_PASSPORT_BIN, "logout", "--client_id", "578aafab312b44f1b76b0529b06bb0c6"],
            capture_output=True, text=True, timeout=10
        )
Confidence
70% confidence
Finding
subprocess.run( [PT_PASSPORT_BIN, "logout", "--client_id", "578aafab312b44f1b76b0529b06bb0c6"], capture_output=True, text=True, timeout=10 )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if is_windows:
        DETACHED_PROCESS = 0x00000008
        CREATE_NEW_PROCESS_GROUP = 0x00000200
        subprocess.Popen(
            ['node', _CLIGUARD_WRAPPER_PATH, '--start'],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
Confidence
70% confidence
Finding
subprocess.Popen( ['node', _CLIGUARD_WRAPPER_PATH, '--start'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
env=env,
        )
    else:
        subprocess.Popen(
            ['node', _CLIGUARD_WRAPPER_PATH, '--start'],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
Confidence
70% confidence
Finding
subprocess.Popen( ['node', _CLIGUARD_WRAPPER_PATH, '--start'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL,

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"const r=addCommonParams(" + json.dumps(url_str) + ");"
            "console.log(r.url)"
        )
        result = subprocess.check_output(['node', '-e', js_code], timeout=5, stderr=subprocess.PIPE)
        injected = result.decode('utf-8').strip()
        return injected if injected else url_str
    except Exception as e:
Confidence
70% confidence
Finding
result = subprocess.check_output(['node', '-e', js_code], timeout=5, stderr=subprocess.PIPE)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
f"const {{signRequest}}=require({json.dumps(_CLIGUARD_PATH)});"
            f"console.log(JSON.stringify(signRequest({json.dumps(method.upper())},{json.dumps(url_str)},{json.dumps(body_hash)})))"
        )
        result = subprocess.check_output(
            ['node', '-e', js_code],
            timeout=5,
            stderr=subprocess.PIPE,
Confidence
70% confidence
Finding
result = subprocess.check_output( ['node', '-e', js_code], timeout=5, stderr=subprocess.PIPE, )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
f"const {{signRequest}}=require({json.dumps(_CLIGUARD_PATH)});"
            f"console.log(JSON.stringify(signRequest({json.dumps(method.upper())},{json.dumps(url_str)},{json.dumps(body_hash)})))"
        )
        result = subprocess.check_output(
            ['node', '-e', js_code],
            timeout=5,
            stderr=subprocess.PIPE,
Confidence
70% confidence
Finding
result = subprocess.check_output( ['node', '-e', js_code], timeout=5, stderr=subprocess.PIPE, )

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The manifest description focuses on dining-related discovery, coupons, and ordering, but the documented behavior explicitly triggers for non-restaurant categories such as supermarket, beauty, digital devices, phones, liquor, pets, flowers, fresh groceries, apparel, maternity, and appliances. It also routes users to external Meituan venue links for pharmacy and one-stop shopping, which materially exceeds the stated restaurant/coupon assistant purpose.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The manifest describes helping users search, claim coupons, and place Meituan orders in conversation, but does not disclose persistent memory retention of consent state or location preferences across future conversations. The code-level instructions permanently write `location_authorized: true` and store preferred city/history in memory, creating a lasting profile beyond the obvious immediate transaction flow.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The manifest describes a conversational Meituan coupon/order helper, but this file also manages authentication state by storing passport auth files and token caches under the user's home directory. While authentication is related, the code exposes standalone capabilities to retrieve cached tokens, poll auth, logout, and clear device identifiers, which is broader than the manifest's described shopping/ordering workflow.

Description-Behavior Mismatch

Low
Confidence
86% confidence
Finding
The manifest says the user can tell the assistant what to eat or where nearby to search, but it does not explicitly disclose that the skill can resolve arbitrary address text into latitude/longitude via a dedicated command. That capability may support nearby search, but it is still an additional concrete behavior not stated in the manifest description.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The manifest describes an in-conversation Meituan ordering and coupon assistant, where network access to Meituan services would be expected. However, this vendored SDK performs global process-side effects on import: it launches a detached daemon and rewrites requests/httpx/urllib behavior for the entire Python process, which is a general-purpose interception capability not justified by the user-facing skill description.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
The manifest describes helping users search deals, get coupons, and place orders, but this module resolves core logic from ~/.cliguard/cliguard-updates when it finds a newer version, then executes that JS with Node via subprocess. Dynamic execution of externally updated code from a writable home-directory location is a software-update capability, not an obvious requirement of the stated ordering assistant purpose.

Context-Inappropriate Capability

High
Confidence
93% confidence
Finding
The file is an obfuscated Node.js wrapper that downloads update metadata and files over HTTP(S), verifies signatures, writes files under temp/update directories, and spawns detached child processes to run a long-lived daemon. Those capabilities are far beyond what is needed to help users search Meituan offers, claim coupons, display listings, or place orders within a conversation.

Description-Behavior Mismatch

High
Confidence
91% confidence
Finding
The manifest describes a consumer-facing assistant for finding restaurants, claiming coupons, showing product lists, and placing orders. This file instead manages a local cliguard installation, checks remote update versions, downloads replacement package files, maintains PID/lock/version files, and controls daemon lifecycle; none of that matches the skill’s claimed end-user functionality.

Context-Inappropriate Capability

High
Confidence
94% confidence
Finding
This file imports OS, filesystem, crypto, zlib, path, and child_process modules and exposes functions such as getFingerprint/getId/signRequest that collect host characteristics including OS details, timezone/locale, installation timestamps, directory counts, and persistent local identifiers. A coupon/search/order assistant may need request signing, but broad device fingerprinting and persistent host profiling are not clearly justified by the manifest’s stated purpose of helping users find deals and place orders in conversation.

Context-Inappropriate Capability

High
Confidence
91% confidence
Finding
The file imports child_process.execSync and uses it in functions that detect OS/version and file metadata, including reading Linux release information and invoking platform-specific commands on macOS and Windows. Spawning local system commands is a strong host-inspection capability that is not justified by the manifest description of a food coupon and ordering assistant.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
Functions around getId create paths under the user environment, write JSON containing identifiers/timestamps, and use a lock file to coordinate access before reading or renaming the stored ID file. Persistent device ID storage is not an obvious requirement for the manifest’s claimed purpose of helping users search deals and place food orders within chat.

Vague Triggers

High
Confidence
98% confidence
Finding
The trigger section covers a very large set of common shopping and dining expressions and states that even vague phrases like “随便吃点什么”, “附近有啥好吃的”, “帮我领个券”, and “薅个羊毛” will trigger the skill. This creates a high risk of unintended invocation because the description does not provide limiting conditions or negative examples to distinguish casual conversation from deliberate skill use.

Missing User Warnings

Medium
Confidence
84% confidence
Finding
The description promises the assistant will automatically claim coupons, search products, and place orders in-chat, but it does not clearly warn at the outset that the skill may use account login, device identifiers, recent location, and local state files to carry out these actions. Although consent appears later for some steps, the top-level skill description lacks a concise user-facing disclosure of these impactful behaviors.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The instructions require the assistant to communicate in a specific conversational style in Chinese (“全程用自然、友好的口语和用户沟通”), but there is no opt-in or alternative language handling. Under the policy, forcing a specific language or locale without user choice is a natural-language policy concern unless clearly justified as region-specific.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The markdown describes invocation examples such as “帮我找外卖”, “推荐附近吃饭的地方”, and “帮我领美团券” as ways to trigger functions. These are natural conversational phrases that could easily appear in ordinary chat, and the document does not define a constrained trigger list, activation boundary, or negative examples to limit unintended invocation.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The document states that users can directly complete ordering and payment in conversation, which can affect user funds and create real-world transactions. Although the file contains general safety language, it does not clearly warn at the point of description that this capability may place paid orders or require careful confirmation before purchase.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This code file contains natural-language instructions, docstrings, and CLI help text that force a specific language for all users. Under the policy, language constraints should either be optional/opt-in or clearly justified as region-specific.

VirusTotal

65/65 vendors flagged this skill as clean.

View on VirusTotal

Static analysis

Detected: suspicious.dangerous_exec, suspicious.secret_argv_exposure

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/run.js:59

Instructions pass high-value credentials through process argv.

Critical
Code
suspicious.secret_argv_exposure
Location
SKILL.md:336