Back to skill

Security audit

VMake

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its advertised Vmake media-processing purpose, but it gives remote responses and user-supplied URLs too much unsandboxed influence over what the agent fetches, shows, and uploads.

Review before installing. Use this only in an environment where uploading media to Vmake and using MT_AK/MT_SK quota is intended, avoid accepting arbitrary URLs from untrusted users, treat Vmake notice text and links as untrusted service content, pin or preinstall dependencies from a trusted source, and clear local task history if result URLs may be sensitive.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:244
Finding
Mandatory Display of Untrusted Server Notices Enables Response and Link Injection<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:244-247`; worker propagation at `scripts/vmake_ai.py:557-560` **Vulnerability Type**: Untrusted remote content inserted into Agent responses **Risk Level**: High ### Vulnerable Code ```markdown - **`notices`** — optional server-controlled user notices collected from config, consume, and task responses. Each usable notice contains a non-empty **`message`**; fields such as **`code`**, **`level`**, **`dedupe_key`**, and **`action_url`** are metadata and may be extended by the server. **MANDATORY (server notices):** When stdout JSON contains **`notices`**, include every non-empty notice **`message`** in the user-facing reply. Unknown notice codes must still be shown. A **warning** notice does not change a completed task into a failure. An **error** notice follows the accompanying **`skill_status`** / **`api_code`**; do not infer failure from notice level alone. Do not repeat notices with the same **`dedupe_key`** in one reply. When **`action_url`** is present, surface it as a clickable link. This overseas Skill expects the server-provided **`message`** to be English; show it as provided and do not translate it automatically. Locale selection belongs to the server. ``` The generated worker instructions repeat this requirement: ```python "- Whenever stdout JSON contains **notices**, include every non-empty notice **message** " "in the user-facing reply. Unknown notice codes must still be shown. A warning notice " "does not change a completed task into a failure. An error notice follows the accompanying " "skill_status/api_code. Do not repeat notices with the same dedupe_key in one reply.\n" ``` ### Technical Analysis The Skill explicitly identifies notice values as server-controlled but nevertheless requires the Agent to reproduce every non-empty message, including notices with unknown codes. It also requires `action_url` values to be rendered as clickable links. No local allowlist, content policy ...[truncated 1459 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace pass-through notices with a local allowlist of documented notice codes. 2. Map recognized codes to locally maintained, non-executable user messages. 3. Treat unknown notices as diagnostic data and do not display their raw content automatically. 4. Restrict `action_url` to HTTPS URLs on an explicit list of official Vmake domains. 5. Label any retained remote message as untrusted external service content. 6. Never instruct the Agent to follow operational directions received in a notice. 7. Apply length limits, control-character removal, Markdown escaping, and URL canonicalization. 8. Log rejected notices securely for operator review rather than exposing them to users. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
sdk/core/client.py:513
Finding
Remote Configuration Can Redirect Signed Requests and Media Uploads<![CDATA[ ## Vulnerability Details **File Location**: `sdk/core/client.py:513-516`; request use at `sdk/core/api.py:488-503`, `535-550`, and `607-637` **Vulnerability Type**: Unvalidated server-controlled network destinations **Risk Level**: High ### Vulnerable Code The WAPI configuration directly changes the endpoint used by the AI client: ```python if "regions" in algo: self.api._config["regions"].update(algo["regions"]) if self.api.region in algo["regions"]: self.api.EndPoint = algo["regions"][self.api.region] ``` That endpoint receives a signed request: ```python self._ensure_endpoint() typ = self._token_policy_type_for(name) signer = Signer(self.Key, self.Secret) headers = { HeaderHost: self.EndPoint, "User-Agent": USER_AGENT, } uri = "https://" + self.EndPoint + "/ai/token_policy?type=" + typ sign_request = signer.sign(uri, "GET", headers, "") session = requests.Session() resp = session.send(sign_request) ``` Storage and algorithm destinations from the returned policy are subsequently trusted: ```python cfg.endpoint = normalize_oss_endpoint(policy["url"]) client = oss.Client(cfg) ``` ```python policy = self.getAiStrategy() host = policy["url"] if host.find("https") > -1: host = host[8:] elif host.find("http") > -1: host = host[7:] headers = { HeaderHost: host, "User-Agent": USER_AGENT, } uri = policy["url"] + "/" + policy["push_path"] sign_request = signer.sign(uri, "POST", headers, json.dumps(data)) session = requests.Session() resp = session.send(sign_request, timeout=policy["sync_timeout"] + 10) ``` Equivalent endpoint assignment and request logic also exists in `scripts/client.py` and `scripts/ai/api.py`. ### Technical Analysis A response from the fixed WAPI host is allowed to supply: - The host receiving later signed token-policy requests. - The algorithm submission and status-query URL. - The object-storage upload endpoint. - Request paths and token-policy types. These values are not constrained ...[truncated 1998 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require HTTPS for every WAPI, algorithm, polling, and storage destination. 2. Canonicalize URLs before validation and reject user-info components, fragments, nonstandard schemes, and malformed hosts. 3. Allowlist exact Vmake API domains and documented cloud-storage domain suffixes. 4. Verify that redirects remain within an approved origin; preferably disable redirects for signed requests. 5. Reject IP-literal, loopback, private, link-local, and reserved endpoint hosts. 6. Validate `push_path` and status paths as relative paths without traversal, schemes, authorities, or control characters. 7. Separate credentials by service so the primary MT_AK/MT_SK signing authority cannot be redirected to arbitrary hosts. 8. Add tests proving that malicious config values such as `http://`, unrelated domains, embedded credentials, and redirecting endpoints are rejected. 9. Apply the same corrections to the mirrored implementations under `scripts/client.py` and `scripts/ai/api.py`. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
sdk/core/client.py:653
Finding
Unrestricted URL Fetching Enables SSRF and Subsequent Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `sdk/core/client.py:653-662`; direct resolver path at `scripts/vmake_ai.py:935-959` **Vulnerability Type**: Server-Side Request Forgery with external upload **Risk Level**: High ### Vulnerable Code The task client accepts any HTTP or HTTPS URL, downloads its response, and uploads it to object storage: ```python if isinstance(image_path, str) and image_path.startswith(("http://", "https://")): preview = api.safe_url_preview(image_path) api._progress_log(f"input: download from URL (GET {preview})") tmp_path, n = self._fetch_http_input_to_tempfile(image_path) try: api._progress_log(f"input: download done ({n} bytes) → OSS upload (PutObject)") self._pipeline_trace.append( {"step": "download_input", "from_url": preview, "bytes": n} ) url = self.api.getFileUrl(tmp_path) ``` The standalone resolver similarly checks only the scheme: ```python elif getattr(args, "url", None): url = args.url.strip() if not url.startswith(("http://", "https://")): _print_json({"error": "Only http:// and https:// URLs are allowed"}) return 1 url_to = skill_config.url_download_timeout_tuple() r = requests.get( url, stream=True, timeout=url_to, headers={ "User-Agent": skill_config.USER_AGENT, }, ) ``` ### Technical Analysis The implementation does not reject loopback, RFC1918 private, link-local, reserved, multicast, or cloud metadata addresses. It also relies on `requests` default redirect handling without validating every redirect destination. A size cap and timeout reduce denial-of-service exposure but do not prevent SSRF. If the URL is used through `run-task`, the downloaded response is automatically uploaded to vendor-controlled object storage. This converts a blind or local SSRF into a direct exfiltration path for any internal endpoint whose response can be fetched. Examples of p ...[truncated 1270 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Resolve the hostname before connecting and reject all non-public IPv4 and IPv6 ranges. 2. Explicitly block loopback, private, link-local, carrier-grade NAT, multicast, reserved, unspecified, and cloud metadata addresses. 3. Disable redirects or independently validate the destination of every redirect hop. 4. Protect against DNS rebinding by connecting only to the validated resolved address and confirming the peer address. 5. Restrict URL inputs to approved media-hosting domains where operationally possible. 6. Route downloads through a hardened egress proxy with network-layer metadata and private-range blocking. 7. Validate media type by magic bytes rather than trusting extensions or `Content-Type`. 8. Keep existing byte and timeout limits, but stream all resolver paths instead of loading complete responses into memory. 9. Apply the same protections to `scripts/client.py`, `scripts/vmake_ai.py`, and delivery helper URL downloads. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/requirements.txt:1
Finding
Runtime Installation Uses Unpinned Dependencies Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `scripts/requirements.txt:1-3`; installation at `scripts/vmake_ai.py:616-629` **Vulnerability Type**: Unsafe dependency resolution and installation **Risk Level**: Medium ### Vulnerable Code ```text alibabacloud-oss-v2>=1.2.0 pytest>=7.2.1 requests>=2.28.2 ``` ```python def cmd_install_deps(_args: argparse.Namespace) -> int: req = SCRIPTS_DIR / "requirements.txt" if not req.exists(): print(json.dumps({"error": "requirements.txt not found", "path": str(req)})) return 1 try: import requests # noqa: F401 import alibabacloud_oss_v2 # noqa: F401 except ImportError: r = subprocess.run( [sys.executable, "-m", "pip", "install", "-q", "-r", str(req)], cwd=str(SCRIPTS_DIR), ) return r.returncode return 0 ``` ### Technical Analysis All dependencies use lower-bound constraints, allowing pip to install any future compatible release. No hashes, lock file, trusted index, or isolated virtual environment are required. Installation executes package build and installation hooks with the privileges of the Agent process. The mandatory workflow directs the Agent to run `install-deps` before catalog discovery. Therefore, dependency installation can occur before the user submits media, and it is part of ordinary Skill activation rather than an exceptional operator-controlled setup step. `pytest` is a test-only package and is not needed for production task execution, unnecessarily expanding the dependency graph and supply-chain exposure. ### Attack Path 1. The required package is absent from the Agent environment. 2. The Agent follows the Skill workflow and invokes `install-deps`. 3. Pip resolves the latest version satisfying each `>=` constraint from the configured index or mirror. 4. A compromised package release, dependency, or package mirror supplies malicious build or installation code. 5. Pip executes that code with th ...[truncated 550 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every production dependency and transitive dependency to an exact reviewed version. 2. Generate a hash-locked requirements file and install with `pip --require-hashes`. 3. Separate development dependencies from runtime dependencies and remove `pytest` from production installation. 4. Use a dedicated virtual environment with minimum filesystem permissions. 5. Configure an explicit trusted package index rather than inheriting arbitrary user or system pip configuration. 6. Perform dependency installation as a deliberate operator setup action, not automatically during task discovery. 7. Run software-composition analysis and periodically regenerate reviewed lock files. 8. Prefer prebuilt, signed artifacts and disable source builds where practical. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/vmake_ai.py:330
Finding
Persistent Task History Stores Complete Potentially Signed Media URLs<![CDATA[ ## Vulnerability Details **File Location**: `scripts/vmake_ai.py:330-359` and `scripts/vmake_ai.py:387-400` **Vulnerability Type**: Sensitive data retained with implicit filesystem permissions **Risk Level**: Low ### Vulnerable Code ```python rec: dict = { "saved_at": datetime.now(timezone.utc).isoformat(), "task_name": task_name, "input": input_src, } if result and isinstance(result, dict): rec["skill_status"] = result.get("skill_status", "unknown") tid = result.get("task_id") if not tid and isinstance(result.get("data"), dict): r = result["data"].get("result") if isinstance(r, dict): tid = r.get("id") if tid: rec["task_id"] = tid if result.get("primary_result_url"): rec["primary_result_url"] = result["primary_result_url"] if result.get("output_urls"): rec["output_urls"] = result["output_urls"] ``` ```python _ensure_state_dir() with open(LAST_TASK_FILE, "w", encoding="utf-8") as f: json.dump(record, f, indent=2, ensure_ascii=False) HISTORY_DIR.mkdir(parents=True, exist_ok=True) ts = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S") hist_path = HISTORY_DIR / f"task_{ts}.json" with open(hist_path, "w", encoding="utf-8") as f: json.dump(record, f, indent=2, ensure_ascii=False) history_files = sorted(HISTORY_DIR.glob("task_*.json")) if len(history_files) > 50: for old in history_files[:-50]: old.unlink(missing_ok=True) ``` ### Technical Analysis The Skill stores the original input, complete result URLs, task identifier, notices, and error data in persistent JSON files. Input and output URLs may contain bearer-style query parameters or temporary storage signatures. The code does not explicitly establish `0700` directory permissions or `0600` file permissions. Actual access therefore depends on the process umask and existing directory permissions. Up to 50 history records are retained, and no time-based expiry or URL-query redaction is perfor ...[truncated 956 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Persist only the task ID, status, task type, and timestamps needed for recovery. 2. Remove URL query strings and fragments before storing any media reference. 3. Create the state directory with mode `0700` and files with mode `0600`, independent of umask. 4. Use atomic writes through a securely created temporary file followed by `os.replace()`. 5. Add time-based expiry and make history retention configurable. 6. Avoid storing server notice bodies and error responses unless explicitly required for diagnostics. 7. Document the retained fields and provide a command to securely clear task history. ]]>
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (116)

Tainted flow: 'token' from os.environ.get (line 45, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
img_bytes = r.content
        filename = image_source.split("?")[0].split("/")[-1] or "image.jpg"
        files = {"photo": (filename, img_bytes, "image/jpeg")}
        resp = requests.post(
            f"{TELEGRAM_API_BASE}/bot{token}/sendPhoto",
            data=data,
            files=files,
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'token' from os.environ.get (line 45, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
sys.exit(1)
        with open(image_source, "rb") as f:
            files = {"photo": (os.path.basename(image_source), f, "image/jpeg")}
            resp = requests.post(
                f"{TELEGRAM_API_BASE}/bot{token}/sendPhoto",
                data=data,
                files=files,
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'token' from os.environ.get (line 35, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
except Exception as exc:
                print(f"[telegram] Thumbnail download error: {exc}, skipping", file=sys.stderr)

        resp = requests.post(
            f"{TELEGRAM_API_BASE}/bot{token}/sendVideo",
            data=data,
            files=files,
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'token' from os.environ.get (line 35, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
def send_text_message(token: str, chat_id: str, text: str) -> tuple[dict | None, str | None]:
    """Send plain text (URLs are linkified by clients)."""
    print("[telegram] Sending download link text", file=sys.stderr)
    resp = requests.post(
        f"{TELEGRAM_API_BASE}/bot{token}/sendMessage",
        json={"chat_id": chat_id, "text": text},
        timeout=(CONNECT_TIMEOUT, 30),
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Dangerous chain: exec() wrapping compile

Critical
Category
Dangerous Code Execution
Content
app_config=vmake_ai.skill_config, sign=types.SimpleNamespace(Signer=Signer),
                   requests=types.SimpleNamespace(Session=lambda: session), json=json,
                   _wapi_meta_code_value=int, WapiApiError=RuntimeError)
        exec(compile(ast.Module(body=[node], type_ignores=[]), "client.py", "exec"), env)
        with patch.dict(os.environ, {}, clear=True):
            client = env["WapiClient"]("test-ak", "test-sk", agent_name="Codex", agent_model="GPT-X")
            self.assertEqual(client.request("/skill/consume.json", method="POST", body={"task": "test"}), {"context": "ok"})
Confidence
95% confidence
Finding
A dangerous execution chain combines code execution (exec/eval) with a dynamic source (network, encoded data, dynamic import), creating a high-confidence attack vector.

Tainted flow: 'token' from os.environ.get (line 989, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
}
            )
            return 1
        r = requests.get(
            f"https://api.telegram.org/bot{token}/getFile",
            params={"file_id": args.telegram_file_id},
            timeout=(CONNECT_TIMEOUT, READ_TIMEOUT),
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'dl_url' from os.environ.get (line 1019, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
)
        filename = f"tg_{uuid.uuid4().hex[:8]}.{extension}"
        dl_url = f"https://api.telegram.org/file/bot{token}/{file_path}"
        r2 = requests.get(
            dl_url,
            timeout=skill_config.url_download_timeout_tuple(),
            headers={
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'feishu_token' from os.environ.get (line 1042, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
{"error": "FEISHU_APP_TOKEN or --feishu-app-token required"}
            )
            return 1
        r = requests.get(
            f"https://open.feishu.cn/open-apis/im/v1/messages/"
            f"{args.feishu_message_id}/resources/{args.feishu_image_key}",
            params={"type": "image"},
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared purpose describes a media-processing skill that talks to a remote Vmake AI service and handles task discovery/execution for image and video restoration. The actual code chunk does none of that. Instead, it is purely an installation utility for deploying the skill files locally. This is a materially different primary purpose and introduces capabilities unrelated to the declared behavior, namely filesystem manipulation, ZIP extraction, package validation, and installer modes for different environments. These installer actions are implementation/deployment behavior, not the declared runtime functionality of the skill. Therefore this code chunk does not accurately represent the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a media-processing integration with specific remote-task orchestration requirements. The actual code chunk is a small utility for preparing optional X-Agent-* headers by reading explicit inputs or SKILL_AGENT_* environment variables, validating/normalizing them, and returning header mappings. This is not merely an implementation detail of the declared behavior because the chunk contains none of the core advertised functionality and instead serves a different, ancillary purpose. Therefore the supplied code does not accurately represent the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description is narrow and policy-heavy: watermark removal and quality restoration only, with mandatory remote catalog discovery and specific task-selection/execution rules. The code chunk instead provides a reusable backend API wrapper for many Vmake/MT AI operations. It can invoke arbitrary configured tasks (`invoke`, `invoke_task`, `run`), includes explicit `txt2img` and `img2img` methods, uploads media to OSS, polls async task status, and stores GID data in a local cache. Those are materially broader capabilities than the declared purpose. Just as importantly, the required behavior in the description is not present: there is no code for remote catalog discovery, no validation that task names come from returned server metadata, no enforcement that legacy aliases are only used when explicitly returned, and no logic implementing the described distinction of video tasks using `spawn-run-task` plus `OpenClaw sessions_spawn` versus image tasks using blocking `run-task`. The pricing claim is not contradicted by this chunk, but the primary purpose and behavioral guarantees do not match the implementation.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This code chunk does not implement the declared Vmake AI watermark-removal or quality-restoration behavior. Instead, it provides a generic persistent cache utility for storing and retrieving gid-associated data on disk. While such a cache could be a supporting helper within a larger system, the chunk itself has a materially different primary purpose from the declared skill behavior and contains none of the described remote catalog discovery, task selection, image/video execution flow, or pricing-related handling.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose describes a media-processing skill for Vmake AI, including catalog discovery, task selection, and image/video restoration workflows. The supplied code does none of that. Its sole purpose is Feishu image messaging: authenticate with Feishu, optionally download an image, upload it to Feishu, and send an image message. This is a materially different primary purpose and uses different external services and local resources than declared. Therefore this is a clear mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This is a clear mismatch. The declared description is about using Vmake AI for watermark removal and quality restoration with specific task-discovery and execution behavior. The supplied code does none of that: it does not contact Vmake, discover any remote catalog, select AI processing tasks, perform image/video restoration, or invoke spawn-run-task/run-task workflows. Instead, its primary and only purpose is sending video/media messages through Feishu/Lark using credentials from local config and Feishu open APIs. That is a materially different purpose and introduces undeclared capabilities and resource access unrelated to the declared skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description is for a media-processing skill that interfaces with Vmake AI and follows specific task-discovery and execution flows. The actual code shown is only a minimal package initializer exporting names from a signing SDK. Based on this chunk alone, the code does not implement or even indicate the described behavior. This is a strong description-to-code mismatch, with the code appearing to serve a different purpose entirely.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This code chunk’s primary purpose is authentication support for HTTP API calls, not Vmake AI media restoration workflows. While such signing could be a supporting component inside a larger Vmake integration, this chunk alone does not perform or orchestrate any of the declared actions: it does not discover tasks, choose legacy aliases, distinguish image vs. video execution paths, create OpenClaw sessions, or invoke remote processing endpoints. Therefore the supplied code does not accurately represent the declared description for this skill and should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This is a clear mismatch. The declared description is about invoking Vmake AI media-processing tasks for watermark removal and quality restoration, including specific task-discovery and execution requirements for image versus video workflows. The supplied code does none of that. Instead, it implements a Telegram image-sending script: it reads TELEGRAM_BOT_TOKEN, accepts a chat ID and image path/URL, optionally downloads the image, and uploads it to Telegram using the sendPhoto endpoint. This is a materially different primary purpose and introduces undeclared external service access and messaging behavior unrelated to the declared skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This is a clear mismatch. The declared description is about watermark removal and quality restoration using Vmake AI task-discovery and task-execution workflows. The supplied code does none of that: it does not discover any remote catalog, invoke Vmake APIs, process images or videos, remove watermarks, restore quality, or handle paid quota/task metadata. Its actual primary purpose is Telegram message delivery, specifically sending a video file and optional link/thumbnail using a bot token. That is a materially different purpose and introduces undeclared network interactions and capabilities unrelated to the declared skill.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description says the skill processes image/video watermark removal and restoration through Vmake AI, including remote catalog discovery and specific task execution patterns. The provided code chunk instead contains only offline tests. It checks fixed endpoint values, normalization/validation of agent name/version/model, shell-safe command construction, preservation of profile arguments, and whether WAPI headers are included before signing. Although these tests reference Vmake AI-related functions and payload builders, they do not implement or invoke the declared end-user capability. This is a material description-versus-behavior mismatch because the actual code’s primary purpose is test/validation infrastructure rather than watermark-removal service execution.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
This code chunk is a top-level __init__.py that re-exports SDK components. Its actual purpose is package exposure/setup for a general Vmake AI SDK, not a concrete skill implementing the described watermark-removal/restoration workflow. Because the declared description is highly specific about operational behavior—catalog discovery, legacy alias handling, spawn vs blocking execution, and paid quota semantics—but none of that behavior appears in the provided code, the description does not accurately represent this chunk. While an __init__.py can be supporting infrastructure, the mismatch should be flagged here because the declared primary purpose is much more specific than the actual visible behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding
This code chunk appears to be a small authentication package initializer, not an implementation of the described Vmake AI media-processing skill. While authentication could be a supporting detail in a larger SDK, the supplied chunk by itself does not perform or demonstrate the declared primary behavior. Because the declared description is about end-user media task orchestration and the actual code only re-exports a Signer class, this is a material purpose mismatch for the supplied code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes a media-processing integration with specific workflow requirements for discovering and invoking Vmake AI tasks. The actual code chunk is a generic authentication helper for signing HTTP requests using HMAC-SHA256 and setting authorization headers. While such signing could be a supporting utility within a larger API client, this chunk by itself does not implement the declared functionality and instead has a materially different primary purpose. Therefore, the description does not accurately represent what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared description is narrowly prescriptive: the skill should process watermark removal and quality restoration with mandatory remote catalog discovery and specific execution mechanisms depending on media type. This code chunk instead exposes a generic command-line interface over SkillClient with three broad operations: run any task by name, query task status, and list tasks from a local configuration object. The list-tasks command explicitly uses INVOKE rather than a remote catalog, which conflicts with the requirement to always discover the remote catalog before naming or selecting a task. There is also no logic to identify image versus video tasks or to route video through spawn/OpenClaw sessions; all task execution goes through one generic run_task path. While use of AK/SK and quota error handling is consistent with a paid API, the implemented behavior is materially broader and different from the declared purpose.

Tp4

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding
The code chunk is a thin generic wrapper around SkillClient.run_task and poll_task_status. While this could support image tasks in a broad sense, it does not implement several core behavioral constraints stated in the description: catalog discovery, task selection based on returned metadata, special handling for video tasks via async spawn/session APIs, or any specialization to watermark removal and restoration. This is a material description-versus-behavior mismatch, not just an omitted implementation detail, because the declared purpose specifies required operational semantics that are absent from the code shown.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description centers on a media-processing integration with Vmake AI, including discovery of remote task metadata, handling image versus video execution paths, and billing-related constraints. The actual code chunk does none of that. It implements a small utility for resolving agent info fields (name, version, model), sanitizing them, optionally reading them from environment variables, and turning them into X-Agent-* headers. This is an unrelated SDK support function rather than the advertised watermark-removal/restoration behavior. Therefore, the description does not accurately represent this code chunk.

Static analysis

No suspicious patterns detected.