Back to skill

Security audit

Zopia

Security checks for vulnerabilities and agentic risk

Overview

This Zopia skill mostly matches its stated video-creation purpose, but it has enough under-scoped account, network, download, and deletion behavior that users should review it carefully before installing.

Install only if you trust Zopia with the prompts, project metadata, generated assets, and account token used by this skill. Prefer an explicit Zopia-only trigger, keep ZOPIA_BASE_URL at the official HTTPS endpoint unless you are deliberately testing locally, avoid confidential content, review downloads before opening them, and be careful with episode deletion because the packaged script does not require confirmation.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/_common.py:32
Finding

Bearer Token Can Be Transmitted to an Arbitrary or Plaintext Endpoint

Content
View full analysis
str: return os.environ.get("ZOPIA_BASE_URL", "https://zopia.ai").rstrip("/") def _build_headers() -> dict[str, str]: return { "Authorization": f"Bearer {_get_access_key()}", "Content-Type": "application/json", } def api_get(path: str, params: dict[str, str] | None = None) -> Any: url = f"{_get_base_url()}{path}" if params: url = f"{url}?{urllib.parse.urlencode(params)}" req = urllib.request.Request(url, headers=_build_headers(), method="GET") return _do_request(req) def api_post(path: str, body: dict[str, Any] | None = None) -> Any: url = f"{_get_base_url()}{path}" data = json.dumps(body or {}).encode("utf-8") req = urllib.request.Request(url, data=data, headers=_build_headers(), method="POST") return _do_request(req) def api_delete(path: str) -> Any: url = f"{_get_base_url()}{path}" req = urllib.request.Request(url, headers=_build_headers(), method="DELETE") return _do_request(req) ``` ### Technical Analysis The destination for every authenticated API request is derived directly from the `ZOPIA_BASE_URL` environment variable. The code does not validate: - Whether the URL uses HTTPS. - Whether the hostname belongs to Zopia. - Whether the destination is a loopback or private-network address. - Whether a redirect changes the request destination to an untrusted origin. The same request attaches `ZOPIA_ACCESS_KEY` as a bearer credential. Consequently, an attacker who can influence the inherited environment can direct authenticated requests to an attacker-controlled endpoint. A plaintext HTTP destination additionally exposes the token and request content to network interception. The project documentation explicitly permits changing ...[truncated 1523 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/download_results.py:43
Finding

Untrusted Session URLs Are Automatically Fetched Without Destination Validation

Content
View full analysis
]+\.(?:png|jpg|jpeg|webp|mp4|mov|webm)', content): url = match.group(0) if url not in seen: seen.add(url) ext = Path(url.split("?")[0]).suffix.lower() media_type = "video" if ext in VIDEO_EXTS else "image" urls.append({"url": url, "type": media_type, "source": "message"}) def download_file(url: str, output_path: str) -> bool: try: req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) with urllib.request.urlopen(req, timeout=60) as resp: ``` ### Technical Analysis Media URLs returned by the remote workspace are accepted without validation. The fallback parser also extracts arbitrary HTTP or HTTPS URLs from message text when they end with a supported media extension. `download_file()` then performs a GET request to each URL. It does not restrict: - HTTP ve ...[truncated 2254 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/download_results.py:76
Finding

Media Download Limit Can Be Bypassed to Exhaust Local Disk Space

Content
View full analysis
bool: try: req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) with urllib.request.urlopen(req, timeout=60) as resp: content_length = resp.headers.get("Content-Length") if content_length and int(content_length) > MAX_FILE_SIZE: return False with open(output_path, "wb") as f: while True: chunk = resp.read(8192) if not chunk: break f.write(chunk) return True ``` ### Technical Analysis The 200 MB limit is enforced only by inspecting the remote server's `Content-Length` header. That header is optional and controlled by the remote server. The check therefore fails to protect against: - Chunked responses without a `Content-Length`. - Responses that omit the header. - Servers that claim a small length and stream more data. - Redirect chains leading to a response with misleading size metadata. The streaming loop does not maintain a cumulative byte count and continues writing until the server closes the response. The 60-second parameter is a socket operation timeout, not necessarily a strict total transfer deadline. A server that continues delivering data can therefore write significantly more than the intended limit. Downloads also run concurrently, with five workers by default, increasing the potential rate of disk and bandwidth consumption. ### Attack Path 1. An attacker places a supported media URL in session-controlled content. 2. The URL points to a server that omits `Content-Length`, uses chunked transfer encoding, or reports a false value belo ...[truncated 1030 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/download_results.py:101
Finding

User-Controlled Filename Prefix Allows Writes Outside the Output Directory

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

声明描述的是一个面向用户的 AI 创作技能,核心功能应是生成视频、图片、剧本、角色和分镜等内容;而提供的代码并未实现任何生成、创作或编排逻辑。它只是调用 query_session 获取已有会话结果,扫描 workspace/messages 中的媒体 URL,然后按类型过滤并下载文件。这与“视频创作技能”的主要用途存在实质性偏差。虽然下载生成结果可能是创作生态中的辅助步骤,但该代码块的主目的明显是媒体结果导出,而不是声明中的 AI 创作流程本身,因此应判定为描述与实际行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a creative-production skill focused on AI-assisted video and image creation workflows. However, the provided code only retrieves Zopia account balance information and outputs it as JSON. This is a materially different primary purpose and introduces an undeclared account/financial querying capability unrelated to the stated triggers about video creation, storyboarding, character design, or script generation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description presents a creative-generation skill for AI-assisted video/image production and storyboarding workflows. However, the code shown does not generate videos, images, scripts, characters, or storyboards, nor does it orchestrate a creation pipeline. Its actual purpose is administrative/data retrieval: listing Zopia projects and formatting their URLs. This is a materially different primary behavior from the declared creative functionality, so the description does not accurately represent the supplied code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

This is a meaningful description-behavior mismatch. The description presents a user-facing creative skill for AI-driven video production across scripts, roles, storyboards, and media generation. The actual code chunk only exposes CLI operations to list, create, and delete episodes in a Zopia project. While episode management could be a supporting part of a multi-episode production system, the implemented behavior in this chunk is administrative and much narrower than the declared purpose. No direct AI generation or creative workflow logic appears here.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The description presents a comprehensive Zopia creative skill for AI-driven video production workflows, including generating scripts, characters, storyboards, images, and videos. However, the provided code only parses command-line arguments and calls helper functions to get or save project configuration fields for a given base/project ID. It does not itself generate media, create scripts, design characters, orchestrate a production pipeline, or trigger on the broad user intents described. This is a material description-behavior mismatch because the actual code chunk is a settings management utility rather than a full video creation skill.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation criteria are extremely broad and mandatory, instructing the system to trigger whenever a request touches AI-assisted video creation or related creative tasks. Overbroad triggering can cause the skill to intercept routine user requests unnecessarily, leading to unexpected external API calls, data disclosure to a third party, or unintended project creation/actions without sufficiently specific user consent.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

The README instructs users to run npx skills add 11cafe/zopia-skills without pinning a specific package version. Because npx resolves and executes the latest published package by default, a compromised upstream package, typosquatted dependency, or malicious future release could execute arbitrary code during installation. In the context of an agent skill installer, this is more dangerous because installation commonly occurs in developer environments with access to source code, tokens, and local files.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
91% confidence
Finding

This second npx skills add example also executes an unpinned CLI version, creating the same supply-chain risk as the primary install command. An attacker controlling or poisoning the resolved package version could run arbitrary code on the user's machine when they target a specific agent installation. The skill context increases risk because users are explicitly encouraged to install tooling that will later handle prompts, local files, and environment variables.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding

The README recommends npx clawhub install zopia-skill without version pinning, exposing users to execution of whatever package version is current at install time. That creates a preventable supply-chain execution path if the package is compromised or updated maliciously. Since this is a skill-distribution path, the command may be run by users expecting a safe marketplace install and therefore not scrutinizing the code being executed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README states that the skill will create projects, send creation instructions, poll progress, and download results, but it does not prominently warn users that their prompts, project data, and generated assets are transmitted to and retrieved from an external service. This omission undermines informed consent and may lead users to share sensitive scripts, intellectual property, or personal data without realizing it leaves the local environment. The risk is heightened here because the workflow is explicitly automated end-to-end, reducing opportunities for the user to notice each external transfer.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill description indicates it should trigger whenever a request involves AI-driven video creation workflows, which is broad and weakly constrained. Overbroad activation can cause the skill to run in contexts the user did not explicitly intend, increasing the chance that prompts, project details, or related content are sent to the external Zopia service unexpectedly. In a creative assistant skill that automates project creation, polling, and downloads, unintended activation materially expands data exposure and remote action risk.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill declares it needs environment access and network-capable behavior through required binaries and API credentials, but it does not define any explicit tool scope such as allowed-tools or permissions. That creates an over-broad execution surface where the runtime may grant more capability than users or reviewers expect, especially for a user-invocable skill that can access external services and local execution.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The example configuration hard-codes '--locale zh-CN', and later examples repeat the same locale without offering the user a language or locale choice. This can violate language/locale policy because it imposes a specific locale by default rather than asking for user preference or documenting a justified regional limitation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation directs the skill to automatically download generated files to the local filesystem after completion, without requiring user confirmation or warning that local writes will occur. Silent filesystem writes can surprise users, consume disk space, overwrite expected paths, or persist sensitive media locally when the user only intended a preview or remote link.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill documents an irreversible delete operation for episodes but does not require a confirmation step or warn that content will be permanently removed. In a user-invocable skill managing creative assets, this creates a real risk of accidental destructive actions and loss of generated work.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown file presents all operational instructions in Chinese and does not offer an alternative language or indicate that the language requirement is region-specific. Under the stated policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The documentation instructs users to run npx clawhub login without pinning an exact package version. Because npx fetches the latest package by default, a compromised, maliciously updated, or typosquatted package version could execute arbitrary code on the publisher's machine during login.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding

The npx clawhub whoami command is invoked without a pinned version, which causes execution of whatever version resolves at runtime. In a publishing workflow, this creates supply-chain risk because an attacker controlling the package or dependency path could run arbitrary code in the user's environment.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The publish command uses npx clawhub publish without version pinning in a release path that likely has access to source code, credentials, and release authority. If the package resolved by npx is malicious or unexpectedly changed, it could exfiltrate code or tokens and publish unauthorized artifacts.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
96% confidence
Finding

The example publish command again relies on unpinned npx clawhub, which is especially risky because it is positioned as a copy-paste release instruction. A compromised package version here could directly affect software distribution and steal developer secrets from the release workstation.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
94% confidence
Finding

The inspection command npx clawhub inspect zopia-skill executes an unpinned package and inherits the same package-substitution and malicious-update risks. Even read-oriented commands can execute arbitrary code before performing their visible function.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.