Back to skill

Security audit

Download Tool

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its video-download purpose, but it can use a paid API key and send video URLs and credentials to a configurable external service without strong scoping or confirmation.

Review before installing. Only use this skill if you trust the external download service and understand that submitted video links, the configured API key, quota checks, task IDs, and resulting videos are handled by that service or by any custom backend you configure. Keep download_tool_base_url on a trusted HTTPS endpoint, and avoid submitting private or tokenized video URLs unless that is acceptable.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/download_video.py:45
Finding

API Key Can Be Transmitted to an Untrusted or Plaintext Backend

Content
View full analysis

Vulnerability Details

File Location: scripts/download_video.py:45-48, 77-88, 110-118; scripts/download_video_simple.py:16-22, 30-31, 47-50, 70-74
Vulnerability Type: Unvalidated credential-bearing network destination
Risk Level: Medium

Vulnerable Code

From scripts/download_video.py:

python
def get_base_url(config=None):
    """获取 API 基础 URL"""
    if config is None:
        config = load_config()
    return config.get("download_tool_base_url", DEFAULT_BASE_URL)
python
def create_download_task(url, api_key, base_url):
    endpoint = f"{base_url}/sys/openapi/download"

    headers = {
        "Content-Type": "application/json",
        "X-Api-Key": api_key
    }

    data = {
        "url": url
    }

    response = requests.post(
        endpoint,
        json=data,
        headers=headers,
        timeout=30
    )
python
def check_download_status(task_id, api_key, base_url):
    endpoint = f"{base_url}/sys/openapi/download/status/{task_id}"

    headers = {
        "X-Api-Key": api_key
    }

    response = requests.get(
        endpoint,
        headers=headers,
        timeout=30
    )

The automatically executed script contains the same pattern:

python
api_key = config.get('download_tool_api_key')
base_url = config.get(
    'download_tool_base_url',
    'https://www.datamass.cn/ai-back'
)

headers = {
    'X-Api-Key': api_key,
    'Content-Type': 'application/json'
}

quota_url = f"{base_url}/sys/openapi/quota"
response = requests.get(quota_url, headers=headers, timeout=10)

download_url = f"{base_url}/sys/openapi/download"
data = {"url": video_url}
response = requests.post(
    download_url,
    json=data,
    headers=headers,
    timeout=10
)

status_url = f"{base_url}/sys/openapi/download/status/{task_id}"
response = requests.get(status_url, headers=headers, timeout=10)

...[truncated 2640 chars]

Remediation
View remediation

Remediation Suggestions

  1. Parse download_tool_base_url with urllib.parse.urlparse before making any request.
  2. Require the https scheme for remote hosts.
  3. Permit plaintext HTTP only for explicit loopback development addresses such as 127.0.0.1 or localhost, and require a clearly named opt-in setting.
  4. Allowlist www.datamass.cn for normal hosted-service operation.
  5. Require explicit user confirmation before sending credentials to any custom hostname.
  6. Reject URLs containing embedded credentials, unexpected ports, fragments, malformed hostnames, or non-HTTP schemes.
  7. Disable automatic redirects for authenticated requests, or validate every redirect destination and remove X-Api-Key whenever the hostname changes.
  8. Store the API key in a dedicated credential store or environment-based secret mechanism rather than a general-purpose JSON file.
  9. Validate that download_tool_api_key is present before constructing authenticated headers in both scripts.
  10. Document that a custom backend receives the API key, video URLs, quota requests, and task identifiers.

T08 · Insecure Dependencies

Note
Location
CLAWHUB_PUBLISH_GUIDE.md:160
Finding

Publishing Guide Uses an Unpinned Globally Installed CLI Dependency

Content
View full analysis

Vulnerability Details

File Location: CLAWHUB_PUBLISH_GUIDE.md:160-165
Vulnerability Type: Unpinned global package installation
Risk Level: Low

Vulnerable Code

bash
npm install -g @openclaw/clawhub-cli
# or
yarn global add @openclaw/clawhub-cli

Technical Analysis

The publishing guide directs users to install the latest available version of a third-party package globally. No exact version, lockfile, integrity value, or provenance-verification procedure is provided.

Because package installation can execute lifecycle scripts, a compromised future release, maintainer account, registry entry, or transitive dependency could execute code under the publishing user's account. Global installation also expands the dependency's reach beyond this project and makes the documented publishing process non-reproducible.

This instruction is not part of ordinary video-download execution and primarily affects developers or maintainers who follow the publishing guide. The audit found no evidence that the currently named package is malicious; the issue is the unsafe dependency-acquisition pattern.

Attack Path

  1. The package, a transitive dependency, its maintainer account, or its registry distribution channel is compromised.
  2. A developer follows the publishing guide after the compromised version becomes the latest release.
  3. The package manager resolves and installs that unreviewed version globally.
  4. Installation lifecycle scripts execute with the developer's user permissions.
  5. Malicious package code accesses files and credentials available to that user or modifies globally accessible tooling.
  6. The compromised CLI may subsequently capture publishing credentials or alter the Skill during publication.

Impact Assessment

The installed package can operate with the privileges of the user running npm or yarn. Potentially exposed assets include:

  • ClawHub or GitHub authentication mate ...[truncated 433 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin the CLI to an exact reviewed version, for example @openclaw/clawhub-cli@X.Y.Z.
  2. Prefer a project-local development dependency instead of a global installation.
  3. Commit and enforce an appropriate package-manager lockfile.
  4. Use npm ci or an equivalent frozen-lockfile installation mode in reproducible environments.
  5. Verify package provenance, publisher identity, signatures where supported, and registry integrity metadata.
  6. Review whether package lifecycle scripts are necessary and disable them during installation when they are not required.
  7. Avoid running package installation with elevated privileges.
  8. Document the tested CLI version and periodically review dependency advisories before updating it.
Vulnerability Patterns
  • 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
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (16)

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document presents the skill as a general-purpose video downloader, but the same file discloses that it actually depends on a private paid external service and an API key. This mismatch can mislead users about trust boundaries, data flow, cost, and deployability, increasing the risk of unintended data disclosure or deceptive distribution of the skill.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises behavior that reads a local config file and sends requests to an external download service, but it does not declare any explicit tool scope or permissions. This creates a permission-transparency gap: users and the hosting framework may not have clear notice that the skill can access local files and perform network egress, increasing the risk of unintended secret access or data transmission.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes broad conditions such as any request containing a video-platform URL or even '任何视频平台的 URL', which can cause the skill to auto-activate in conversations where the user did not clearly request use of this external service. In this skill's context, unintended invocation is more dangerous because activation can lead to reading a local API key and sending the supplied URL to a third-party paid service.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill reads both an API key and a caller-influencing service base URL from local configuration, then uses them for authenticated outbound requests. This broadens the trust boundary: if the config is modified or points to an attacker-controlled host, the skill may send the API key and user-submitted URLs to an unintended server, creating credential-exposure and data-exfiltration risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
87% confidence
Finding

This line transmits user-supplied content to an external service, which is functionally necessary for the skill but still security-relevant because it moves potentially sensitive user data off-host. In this skill context, that transmission is expected, yet it becomes more dangerous because the destination can be overridden via config and the user is not clearly warned at execution time.

Content

Scanner excerpt · scripts/download_video.py (reported line 87)May include surrounding context.

python
"url": url
    }

    response = requests.post(endpoint, json=data, headers=headers, timeout=30)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'endpoint' from requests.post (line 114, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/download_video.py (reported line 87)May include surrounding context.

python
"url": url
    }

    response = requests.post(endpoint, json=data, headers=headers, timeout=30)
    response.raise_for_status()

    result = response.json()

Tainted flow: 'endpoint' from requests.post (line 114, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/download_video.py (reported line 120)May include surrounding context.

python
"X-Api-Key": api_key
    }

    response = requests.get(endpoint, headers=headers, timeout=30)
    response.raise_for_status()

    result = response.json()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The tool forwards the user's provided video URL to a third-party service, but there is no explicit privacy notice or confirmation at the point of use. URLs can contain sensitive identifiers, private share links, tracking parameters, or account-related metadata, so silent transmission can expose user data beyond what they reasonably expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script reads an API key from local configuration and automatically transmits it to a remote service in the X-Api-Key header without any explicit disclosure, confirmation, or trust validation to the user. In an agent skill context, silent credential use is sensitive because users may not realize a local secret is being accessed and sent to a third-party endpoint configured in base_url.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script sends the user-provided video URL to a remote API without an explicit warning that the URL and associated metadata will leave the local environment. In this skill context, external transmission is expected for functionality, but the absence of transparency and consent still creates a privacy and data-sharing risk, especially if users submit private or tokenized URLs.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

The script transmits user-supplied data (video_url) and an authentication header to an external service. In a download skill this network behavior is functionally expected, but it is still security-relevant because it shares potentially sensitive URLs and uses a secret against a remote endpoint that is configurable, creating privacy and trust-boundary concerns.

Content

Scanner excerpt · scripts/download_video_simple.py (reported line 59)May include surrounding context.

python
download_url = f"{base_url}/sys/openapi/download"
    data = {"url": video_url}

    response = requests.post(download_url, json=data, headers=headers, timeout=10)

    if response.status_code == 200:
        result = response.json()

Tainted flow: 'status_url' from requests.post (line 71, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/download_video_simple.py (reported line 77)May include surrounding context.

python
while attempt < max_attempts:
            try:
                response = requests.get(status_url, headers=headers, timeout=10)

                if response.status_code == 200:
                    status_response = response.json()

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

该文件从标题到全部操作说明均以中文编写,未见提供其他语言选项、用户可选语言声明,或说明该文档仅面向特定中文用户群体。根据语言/区域政策,若技能或其发布指导默认强制单一语言且无用户选择,可能构成自然语言层面的策略问题。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The manifest description is written only in Chinese, which can indicate a language-specific constraint without any opt-in or multilingual alternative. Under the policy rule, language/locale restrictions should be explicitly optional or justified when they affect how users interact with the skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

All user-facing help, errors, and status messages in the file are written only in Chinese, which effectively imposes a language choice on users. The file does not offer an alternate language, locale selection, or indicate that the tool is intentionally limited to a Chinese-speaking audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
98% confidence
Finding

All user-facing status and error messages are written in Chinese, with no option to select another language or locale. This can violate language/locale policy when users are not given a choice or when the locale restriction is not documented as intentional.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.