Back to skill

Security audit

Movie Recommender - 电影推荐

Security checks for vulnerabilities and agentic risk

Overview

This movie recommendation skill is coherent and purpose-aligned, with disclosed Douban lookups and local movie-list storage but some privacy and reliability caveats.

Before installing, understand that movie searches may be sent to Douban and that cache, watched-history, and wishlist JSON files may be stored locally. Avoid recording sensitive viewing preferences on shared machines, and review or delete the generated JSON files if you do not want that history retained. The watched/wishlist command parsing is also incomplete and may save placeholder entries.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (14)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The documentation describes real-time Douban lookups and crawling/API usage without warning that user queries may be transmitted to an external service. Even simple movie searches can reveal user interests, language, or behavior patterns, and undisclosed third-party transmission is a meaningful privacy issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README advertises viewing-record and wishlist management but does not clearly disclose that movie history and user ratings are persisted locally. This can mislead users into sharing behavioral data without informed consent, creating privacy and retention risks if the files are later exposed or accessed by other components.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example trigger phrases are ordinary conversational requests like asking for movie recommendations, which creates a real risk of over-broad or unintended activation in a host assistant. In a multi-skill environment, generic phrasing can cause this skill to intercept unrelated user requests and process them without clear user intent to invoke it.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger phrases are very broad and map to ordinary movie-related conversation, so the skill may activate in situations the user did not explicitly intend. In a skill with network access and local file write capability, ambiguous invocation increases the chance of unintended scraping, recommendation actions, or persistence of viewing data without clear user consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly requests network access, web scraping, and local file storage, but it does not disclose what user data may be sent externally, scraped, stored locally, or retained over time. This creates privacy and transparency risks, especially because movie preferences, ratings, and comments can reveal sensitive interests or habits and may be persisted without informed consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file's natural-language descriptions and all user-facing responses are written in Chinese, and the trigger/interaction model assumes Chinese input terms such as moods and commands. There is no opt-in, language selection, or documented justification that this skill is intended only for a Chinese-language locale.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill persists watch history and watchlist data to local JSON files without any user-facing disclosure, consent prompt, or retention notice. In an agent setting, silent storage of user preferences and activity can expose sensitive behavioral data, especially on shared systems or where users do not expect persistent logging.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Movie lookups send user-provided queries to an external Douban-backed API/search layer without explicitly informing the user that their input is transmitted off-device. User queries can reveal preferences, interests, or personal context, so undisclosed external transmission is a privacy risk in this skill context.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The help text says users can record a specific movie and rating (for example, "我看了 XXX,评分 5 分"), but the implementation does not parse the movie name or rating at all. Instead it always calls add_watched("未知电影", comment="自动记录"), contradicting the stated behavior rather than merely omitting a minor detail.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The default help advertises functionality like "把 XXX 加入想看", implying the skill will add the requested title. However, the implementation ignores the query content and always saves "未知电影", which directly conflicts with the described capability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

All user-facing instructions, examples, and outputs are presented in Chinese, which effectively imposes a single language without documenting an opt-in or locale-specific scope. Under the language/locale policy, this is a natural-language constraint unless the skill clearly offers alternatives or justifies a China-specific audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The request headers hard-code Accept-Language to prefer zh-CN, which imposes a specific language/locale behavior in the skill's network interactions. This matches the policy category for language or locale constraints because the file does not indicate user opt-in or a documented region-specific necessity.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module-level documentation states the implementation uses a web-scraping approach and does not rely on an API, while this docstring says the fallback is used 'when the Douban API is unavailable'. That is an active contradiction in the code documentation about what upstream mechanism the skill actually depends on.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function get_hot_movies is documented as fetching popular/currently showing movies, but it directly calls get_top250(start=0), which is a ranked Top250 list rather than a hot/in-theaters feed. This is an active contradiction between the inline documentation/name and the implemented behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.