T09 · Insecure Skill Coding Practices
- Location
scripts/subscribe_callback_handler.py:12- Finding
MoviePilot Credential Transmitted to a Hard-Coded Plaintext Endpoint
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill sends Feishu cards but also runs callback workflows that can create MoviePilot subscriptions and handle credentials in unsafe ways, so it needs careful review before installation.
Install only if you intentionally want a Feishu-to-MoviePilot automation, not just a card sender. Before use, require HTTPS and an explicit MoviePilot base URL, remove the hard-coded default endpoint, require Feishu callback signature verification, bind callbacks to the original recipient and media, restrict poster downloads to trusted HTTPS image hosts, and protect or avoid plaintext token caches and persistent callback state.
scripts/subscribe_callback_handler.py:12MoviePilot Credential Transmitted to a Hard-Coded Plaintext Endpoint
scripts/feishu_callback_worker.py:14Public Callback Listener Accepts Unsigned Requests When Its Encryption Key Is Unset
scripts/send_feishu_card.py:334Unrestricted Poster URL Fetch Enables SSRF and Local File Exfiltration
scripts/card_callback_router.py:15Feishu Tenant Bearer Token Stored in a Predictable File Without Explicit Access Controls
scripts/card_callback_router.py:115Callback Authorization Is Not Bound to the Original Card Recipient or Stored Media Data
scripts/feishu_callback_worker.py:315Sensitive Feishu Callback Tokens and User Identifiers Are Written to Logs
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
The skill claims to send Feishu card messages, but the documented callback flow performs MoviePilot subscription queries/creation, reads local credentials for external services, and maintains local idempotency state. Hidden cross-system write capabilities materially elevate risk because a user invoking a messaging skill may unknowingly authorize writes to another external system.
This document describes callback handling that can create MoviePilot subscriptions, which is materially broader than the declared purpose of a skill that should only send Feishu interactive cards via OpenAPI. That scope expansion introduces an undeclared write path into an external system, increasing the chance of unauthorized actions through crafted callback payloads or operator misuse.
The documented behavior includes querying and writing to an external MoviePilot subscription API, which gives this skill side-effecting capabilities unrelated to Feishu card delivery. In the context of a messaging skill, such hidden integration is especially risky because interactive card callbacks can become a bridge for unauthorized state changes in another system if not strongly bound to authenticated users and approved actions.
The script executes a separate local handler with user-controlled payload data, creating an additional execution boundary and broadening the skill from simple card sending into local orchestration of other code. In a skill context, this is dangerous because any weakness or unexpected behavior in the downstream handler inherits the privileges of this process and may process untrusted callback data.
The skill metadata says it only sends Feishu cards via OpenAPI and does not use the message channel, but this file exposes a network listener on 0.0.0.0:18081, accepts Feishu callbacks, decrypts/verifies requests, extracts user identity, and routes actions into another local script. That is a materially broader capability than declared, increasing attack surface and enabling external event-driven behavior that users and operators would not reasonably expect from a send-only skill.
The file performs MoviePilot subscription creation and lookup based on callback input, which is outside the declared scope of a Feishu card sender skill and introduces privileged side effects on an external system. This scope mismatch is dangerous because users or reviewers may authorize a messaging skill while the code actually drives subscription-management actions using stored credentials and network calls.
The skill documentation exposes capabilities that imply environment access, local file read/write, shell execution, and network access, but it does not declare any tool scope restrictions such as permissions or allowed-tools. This creates an over-privileged skill surface where an agent may invoke broader capabilities than a user would reasonably expect from a 'send Feishu card' utility.
The documentation instructs sending card content and recipient identifiers such as open_id/chat_id to Feishu, but it does not clearly warn users that their content and identifiers will be transmitted to an external service. This omission can lead to unintended disclosure of sensitive data, especially when the card payload includes structured notifications or personal information.
The documentation describes the skill as only sending Feishu cards, but later declares callback routing and automatic 'subscribe now' handling that writes into MoviePilot. This is a scope deception issue: hidden side effects on an external system can surprise users and bypass informed approval of state-changing operations.
The callback flow automatically performs subscription writes to MoviePilot after a card action, but the documentation does not provide a clear user-facing warning that this modifies external system state. Automatic write actions tied to callbacks can cause unintended subscriptions or business-side effects without sufficiently informed consent.
This JSON manifest contains user-facing validation messages entirely in Chinese, such as "title 不能为空" and the poster guidance text, with no indication that the skill is China-specific or that users can opt into the locale. The policy explicitly calls out language or locale policy violations when a skill forces a specific language without user opt-in.
This JSON file contains multiple user-facing validation/error messages in Chinese, such as 'title 不能为空' and the longer poster image guidance text. Because the file provides only Chinese output and does not offer locale selection or document a justified region-specific constraint, it creates a language/locale policy issue under the natural-language policy category.
This JSON template contains user-facing labels such as '剧情简介' and other Chinese text directly in the rendered content. Because the file forces a specific language in multiple UI strings and provides no user opt-in or locale selection, it violates the language/locale policy for natural-language content.
The header title is fixed as '🎬 《${title}》电影介绍', which presents the card in Chinese regardless of user language preference. This is a natural-language policy issue because the template enforces one language rather than offering a configurable or justified locale.
This JSON template contains multiple user-facing strings in Chinese, such as section headings and button text, and does not indicate any user opt-in or locale selection. That creates a language-policy issue because the skill appears to force a specific language for all users rather than offering a choice or documenting a region-specific constraint.
The worker builds and executes an external Python command via subprocess.run to process queued jobs, but there is no confirmation prompt, user-visible logging, or explanatory comment/docstring disclosing that external command execution will occur. For a code file, subprocess or shell execution should have some visible disclosure unless clearly documented as part of the skill's stated purpose in accompanying markdown, which is not evident from this file alone.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
'--account-id', str(data.get('account_id', '1')),
'--payload', json.dumps(data['payload'], ensure_ascii=False),
]
return subprocess.run(cmd, capture_output=True, text=True, timeout=180)
def recover_orphan_processing_files():
The cleanup_history function silently deletes files beyond retention limits using unlink, and the finally block also deletes claimed job files after processing. The file contains no user-facing warning, logging, or explanatory comment describing these deletions, which are safety-relevant file operations under the code-file criteria.