Back to skill

Security audit

猫眼电影票购票助手

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Maoyan ticket-booking assistant, but it handles account tokens and generated shell commands in ways that need careful review before installation.

Install only if you are comfortable giving this skill access to your Maoyan session and letting it create ticket orders after your confirmations. Before use, the publisher should replace returned shell command strings with structured shell-free execution, validate channel and target identifiers, stop emitting AuthKeys in tool output, and use safer credential storage or authorization flow.

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

Error
Location
scripts/send-qr.mjs:12
Finding

Shell Command Injection Through Unescaped Conversation Context

Content
View full analysis
Remediation
View remediation
", "--target", "", "--media", "", "--message", "" ] } ``` 3. Invoke the process through a shell-free API such as `spawn()` or `execFile()` with an argument array and `shell: false`. 4. Apply strict allowlists to `channel` and `targetId`. Reject values containing whitespace, control characters, shell metacharacters, or characters outside the platform's documented identifier syntax. 5. Do not rely exclusively on shell escaping. Validation plus shell-free execution should be the primary security controls. 6. Update `SKILL.md` so the Agent never executes dynamically generated command strings. 7. Add tests containing values such as semicolons, command substitutions, quotes, newlines, and option-like prefixes to verify that they are rejected or treated strictly as arguments. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/get-hot-movies.mjs:67
Finding

Session Token Exposure in URL Query Strings

Content
View full analysis
{ const input = mapAuthKey(await readJsonInput()); const limit = normalizeLimit(input.limit, 10); const token = input.token || ""; const params = new URLSearchParams(); if (token) params.set("token", token); if (input.ct) params.set("ct", input.ct); const ci = input.cityId ?? input.ci; if (ci != null) params.set("ci", ci); if (input.channelId != null) params.set("channelId", input.channelId); const url = `${MAOYAN_API_URL}?${params.toString()}`; const controller = new AbortController(); const timer = setTimeout( () => controller.abort(), DEFAULT_TIMEOUT_MS ); let res; try { res = await fetch(url, { method: "GET", headers: generateMaoyanHeaders({ token, uuid: input.uuid, extraHeaders: { Accept: "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "jQuery", "M-APPKEY": "fe_canary" }, }), signal: controller.signal, }); ``` The same pattern is present in the movie-to-cinema lookup: ```javascript const token = input.token || ""; ``` ```javascript if (token) params.set("token", token); const url = `${MAOYAN_API_URL}?${params.toString()}`; const controller = new AbortController(); const timer = setTimeout( () => controller.abort(), DEFAULT_TIMEOUT_MS ); let res; try { res = await fetch(url, { method: "GET", headers: generateMaoyanHeaders({ token, uuid: input.uuid, channelId: input.channelId ?? CHANNEL_ID }), signal: controller.signal, }); ``` ### Technical Analysis When an optional `token` or `authKey` is supplied, the discovery scripts place the session credential in the request URL. ...[truncated 1924 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
scripts/validate-maoyan-authkey.mjs:86
Finding

Authentication Validator Returns the Raw Session Token in Tool Output

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (45)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 69)May include surrounding context.

md
echo '{"ci": <cityId 或 1>}' | node scripts/get-hot-movies.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 98)May include surrounding context.

md
echo '{"keyword": "<影片名>", "cityId": <cityId>}' | node scripts/search-movies.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 120)May include surrounding context.

md
- 已知 movieId → `get-cinemas-by-movie.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 121)May include surrounding context.

md
- 用户提供位置 → `get-nearby-cinemas.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 122)May include surrounding context.

md
- 按名称搜索 → `search-cinemas.mjs`

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 145)May include surrounding context.

md
echo '{"cinemaId": <cinemaId>, "cityId": <cityId 或 1>}' | node scripts/get-showtimes.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 187)May include surrounding context.

md
echo '{"seqNo": "<seqNo>", "ticketCount": <ticketCount>}' | node scripts/get-seat-map.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 212)May include surrounding context.

md
echo '{"rows": <seatMapRows>, "centerSeats": [{"rowId": "<rowId>", "columnId": "<columnId>", "mark": "★"}]}' | node scripts/render-seat-map.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 255)May include surrounding context.

md
echo '{"orderId": "<orderId>"}' | node scripts/query-ticket-status.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 330)May include surrounding context.

md
echo '{"seqNo": "<seqNo>", "cityId": <cityId>, "seats": {"count": <ticketCount>, "list": [<座位对象列表>]}}' | node scripts/create-order.mjs

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 363)May include surrounding context.

md
echo '{}' | node scripts/get-payment-link.mjs

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrases are broad enough to match casual movie-related conversation such as asking for recommendations or nearby cinemas, which can invoke a transactional purchasing skill without strong evidence the user wants automation. In a payment-capable ticket-booking context, unintended invocation increases the chance of collecting state, steering users into login/payment flows, or causing confusion around consent and intent.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly treats vague statements like 'I want to watch a movie' as a default entry into the booking flow, which weakens intent validation and can funnel users toward commerce actions from ambiguous conversation. Because this skill supports login, order creation, and payment guidance, the ambiguity is more dangerous than in a non-transactional recommendation-only skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

Multiple sections prescribe fixed Chinese output and exact Chinese phrases for user interaction, including required endings and fixed login/payment copy. The file does not offer users a language or locale choice, nor does it state that the skill is intentionally restricted to Chinese-speaking users for a documented regional-compliance reason.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The entire reference content is written only in Chinese and provides all user-facing guidance in that locale, with no indication that language choice is optional or limited to a justified region-specific context. Under the policy rules, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documents collection and use of precise latitude/longitude to find nearby cinemas, but gives no user-facing notice, consent boundary, or data-minimization guidance. In a ticket-booking skill, location is sensitive personal data; unnecessary retention, transmission, or silent use can expose a user's whereabouts or home/work patterns if mishandled.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The documented APIs load, validate, save, and clear a local AuthKey token, but provide no warning that an account credential is being stored locally or guidance on secure handling. Persistent bearer-token storage can enable account takeover, unauthorized purchases, or access to order data if the token is exposed through logs, weak filesystem permissions, or reuse across sessions.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The create-order flow has a real side effect: it locks seats and reserves inventory, yet the documentation lacks a warning that invoking it changes system state before payment. In a booking context, accidental or premature invocation can deny availability to others, create user confusion, and potentially facilitate nuisance reservation abuse or unintended orders.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The send-qr API transmits channel identifiers and login/payment QR content to an external messaging channel, but the documentation does not warn about external disclosure or link-handling risks. If misrouted, intercepted, or sent to the wrong target, login or payment links could expose account access, payment opportunities, or personal identifiers to unintended recipients.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The shared code persists both a device identifier and authentication material under the user's home directory, creating long-lived local secrets outside the immediate runtime. In a movie-ticket booking skill, persistent token storage may be operationally convenient, but it increases exposure to credential theft, session reuse, and cross-run tracking if the host is shared, compromised, or logs/backups capture these files.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code deliberately generates anti-scraping headers and labels them as such, indicating an attempt to bypass or emulate protected client behavior rather than only performing straightforward ticket-booking requests. That expands the skill's capability beyond normal user-facing booking logic and may facilitate unauthorized scraping or evasive access patterns against the upstream service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The request header hard-codes Accept-Language to prefer zh-CN, which imposes a specific language/locale policy on all users of this shared helper. The file does not provide an opt-in, override requirement, or documented region-specific justification for this constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file's natural-language interface documentation is entirely in Chinese, including required input/output descriptions and runtime error messages later in the file. This imposes a specific language/locale on users or operators without offering a choice or documenting that the skill is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's user-facing natural-language strings and instructions are entirely in Chinese, including the description and the instruction telling the user how to proceed. There is no indication that the skill offers a language choice or that the Chinese-only locale is a documented, justified requirement, which can violate language/locale policy.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script explicitly instructs the user to retrieve an AuthKey from Maoyan and paste it back into the chat, which exposes a sensitive authentication secret to the agent runtime, logs, intermediaries, and any connected tooling. Because this skill supports a full ticket-purchase workflow, compromise of that key could enable account access or unauthorized transactions within the user's ticketing context.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.