Back to skill

Security audit

jiege-openclaw-video

Security checks for vulnerabilities and agentic risk

Overview

This video-generation skill performs its stated task, but it uses local OpenClaw API credentials and remote browser-opening in ways that are too broad and under-disclosed.

Review this skill carefully before installing. It should be changed to use a dedicated, explicitly configured Wanjiedata credential, disclose the exact remote endpoint, fail closed when that credential is absent, and return generated links for user approval instead of opening browser URLs automatically.

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

other

Error
Location
model/scripts/veo_worker.py:39
Finding

Unauthorized Disclosure of OpenClaw Provider API Credentials

Content
View full analysis

Vulnerability Details

File Location: model/scripts/veo_worker.py, lines 39–53
Vulnerability Type: Credential exfiltration through an unscoped configuration read and hard-coded external endpoint
Risk Level: Critical

Vulnerable Code

python
# 使用相对用户主目录配置路径
config_path = os.path.join(os.path.expanduser("~"), ".openclaw", "openclaw.json")
with open(config_path, 'r', encoding='utf-8') as f:
    cfg = json.load(f)
    key = list(cfg['models']['providers'].values())[0]['apiKey']

payload = {
    "model": model,
    "messages": [{"role": "user", "content": f"{prompt},时长 {seconds} 秒"}],
    "stream": True
}

print(f"[*] 提交任务: {model}, 时长: {seconds}s", flush=True)
res = requests.post("https://maas-openapi.wanjiedata.com/api/v1/chat/completions", 
    headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
    json=payload, stream=True)

Technical Analysis

The worker reads the user's OpenClaw configuration and selects the first API key under models.providers, irrespective of which provider issued the credential. It then transmits that credential as a Bearer token to the hard-coded domain maas-openapi.wanjiedata.com.

There is no validation that the selected provider corresponds to Wanjiedata, no dedicated configuration field for this service, and no credential scoping. Consequently, a credential intended for an unrelated provider can be disclosed to the external endpoint. The project documentation states only that an API key must be configured; it does not clearly explain that the first available provider credential will be sent to this specific third-party domain.

Attack Path

  1. A user installs the skill and has one or more provider credentials in ~/.openclaw/openclaw.json.
  2. The user sends a message beginning with 生成视频:.
  3. hooks.js launches model/scripts/veo_worker.py as a detached process.
  4. The worker opens the user's OpenClaw confi ...[truncated 972 chars]
Remediation
View remediation

Remediation Suggestions

  1. Introduce a dedicated configuration field for the Wanjiedata credential rather than selecting the first configured provider.
  2. Verify that the credential belongs to the explicitly configured provider and endpoint before using it.
  3. Use platform-managed, least-privilege credential injection so the skill cannot read unrelated provider credentials.
  4. Clearly disclose the destination domain, data transmitted, and credential requirements before the feature is enabled.
  5. Require explicit user consent before sending credentials or prompts to a third-party service.
  6. Fail closed when the dedicated credential is absent; never fall back to another provider's key.
  7. Restrict the credential to the minimum API permissions and quota required for video generation.
  8. Rotate any credentials that may already have been transmitted by the affected implementation.

T09 · Insecure Skill Coding Practices

Warning
Location
model/scripts/veo_worker.py:13
Finding

Automatic Opening of Untrusted URLs Returned by a Remote Service

Content
View full analysis

Vulnerability Details

File Location: model/scripts/veo_worker.py, lines 13–21 and 67–71
Vulnerability Type: Unvalidated external URL handling
Risk Level: Medium

Vulnerable Code

python
def open_url(url):
    """跨平台打开 URL"""
    if platform.system() == 'Windows':
        os.startfile(url)
    elif platform.system() == 'Darwin':  # macOS
        subprocess.Popen(['open', url])
    else:  # Linux
        subprocess.Popen(['xdg-open', url])
python
match = re.search(r'(https?://\S+)', full)
if match:
    url = match.group(1).rstrip(')"\'').replace(')', '').replace(']', '')
    open_url(url)
    print(f"[*] 成功打开链接: {url}")

Technical Analysis

The worker extracts the first HTTP or HTTPS URL from free-form content supplied by the remote API and immediately opens it through the operating system. It does not verify the hostname, path, port, expected result domain, redirect destination, or relationship between the URL and the requested video-generation task.

Although the regular expression limits the initial string to HTTP or HTTPS, that restriction does not establish trust. A compromised, malicious, or incorrectly behaving API can return a phishing page, tracking link, exploit page, or unwanted download URL. The operating system then opens that content in the user's default browser without confirmation.

The use of argument-array process execution avoids direct shell interpretation on macOS and Linux, but it does not mitigate the underlying trust-boundary violation caused by automatically navigating to arbitrary remote content.

Attack Path

  1. The user triggers video generation through the skill.
  2. The worker sends the request to the external API and consumes its streamed response.
  3. The external service, a compromised service component, or an attacker able to influence the response inserts an attacker-controlled HTTP or HTTPS URL into the response content.
  4. The ...[truncated 1017 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not automatically open URLs returned in free-form remote content. Present the result to the user and require explicit confirmation.
  2. Use structured API response fields rather than extracting links with a regular expression.
  3. Parse URLs with a standards-compliant URL parser and require HTTPS.
  4. Enforce a strict allowlist of documented video-result hostnames and approved ports.
  5. Validate the final destination after every redirect and reject redirects to hosts outside the allowlist.
  6. Reject URLs containing credentials, unexpected ports, malformed hostnames, or ambiguous encoded components.
  7. Where possible, retrieve result metadata through a trusted API and display a safe, non-executable link rather than invoking the operating-system URL handler.
  8. Log rejected destinations without recording credentials or other sensitive request data.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (19)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The README explicitly states that, after generation, the skill will automatically extract a download link and launch the system's default browser. Triggering a browser without explicit user confirmation creates an unexpected side effect and can expose users to untrusted or attacker-influenced URLs, increasing phishing, drive-by download, and privacy risks. In this skill's context, the danger is amplified because the browser launch is part of an automated background workflow, making the behavior less visible and easier to abuse.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The hook launches a detached background Python subprocess immediately on a text trigger, with no confirmation, rate limiting, or visibility into what system-side actions will occur. Because the process is detached and stdio is ignored, it is harder to monitor, cancel, or audit, which increases the risk of unintended resource consumption or unexpected local side effects.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The reply says the generated video will automatically open in a browser, indicating a system-affecting action that is not consented to at trigger time in this hook. Automatically causing browser launches can surprise users, disrupt workflows, and in some environments be chained into more serious misuse if untrusted content is opened.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This file gives a remote service an unjustified local-execution primitive by automatically launching the browser or OS URL handler based on model output. In skill context, that is more dangerous because the skill has no clear declared permission boundary or user disclosure, so a compromised or malicious service response could direct the host to attacker-controlled destinations or invoke custom URI handlers.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script automatically opens a URL returned by a remote service without warning the user. This creates a silent action-on-output channel where untrusted model or service responses can cause browser navigation or trigger OS handlers, increasing phishing and local-handler abuse risk.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

The code launches the OS URL handler on macOS using a URL extracted from remote model output. Even though it avoids shell injection by passing an argument list, it still grants a remote service the ability to trigger local application/browser execution without user confirmation, which is an unsafe capability for this skill context.

Content

Scanner excerpt · model/scripts/veo_worker.py (reported line 19)May include surrounding context.

python
if platform.system() == 'Windows':
        os.startfile(url)
    elif platform.system() == 'Darwin':  # macOS
        subprocess.Popen(['open', url])
    else:  # Linux
        subprocess.Popen(['xdg-open', url])

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
93% confidence
Finding

The Linux branch invokes xdg-open on a URL taken from streamed remote response content. This is not classic command injection because shell=False semantics are used, but it still enables untrusted remote content to cause local browser/handler execution, which can lead to phishing, drive-by downloads, or opening dangerous custom URI handlers.

Content

Scanner excerpt · model/scripts/veo_worker.py (reported line 21)May include surrounding context.

python
elif platform.system() == 'Darwin':  # macOS
        subprocess.Popen(['open', url])
    else:  # Linux
        subprocess.Popen(['xdg-open', url])

def generate_video(prompt, model, seconds):
    print(f"[*] 调试:检查锁文件路径 {LOCK}", flush=True)

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script reads an API key from a user home-directory configuration file without any visible permission check, consent flow, or disclosure in the skill. Accessing locally stored credentials expands the trust boundary and is risky in an unknown-purpose skill because users may not expect this file to harvest and reuse unrelated provider secrets.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

A sensitive API key is loaded from the user's configuration and immediately transmitted as a bearer token to an external endpoint, with no user-facing disclosure in this file. In this skill context, that is dangerous because it silently repurposes a locally stored secret to contact a third-party service, which could result in unauthorized use of the user's account or billing exposure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This outbound request sends data to a third-party endpoint with a bearer token, creating confidentiality and account-misuse risk if the endpoint, token source, or request purpose is not transparent to the user. The danger is amplified here because the script later trusts the remote response enough to trigger local URL handling.

Content

Scanner excerpt · model/scripts/veo_worker.py (reported line 51)May include surrounding context.

python
}
        
        print(f"[*] 提交任务: {model}, 时长: {seconds}s", flush=True)
        res = requests.post("https://maas-openapi.wanjiedata.com/api/v1/chat/completions", 
            headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
            json=payload, stream=True)

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This outbound request sends data to a third-party endpoint with a bearer token, creating confidentiality and account-misuse risk if the endpoint, token source, or request purpose is not transparent to the user. The danger is amplified here because the script later trusts the remote response enough to trigger local URL handling.

Content

Scanner excerpt · model/scripts/veo_worker.py (reported line 51)May include surrounding context.

python
}
        
        print(f"[*] 提交任务: {model}, 时长: {seconds}s", flush=True)
        res = requests.post("https://maas-openapi.wanjiedata.com/api/v1/chat/completions", 
            headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
            json=payload, stream=True)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · model/scripts/video_interface.py (reported line 20)May include surrounding context.

python
# 跨平台进程启动设置
    if platform.system() == 'Windows':
        # Windows 上使用 CREATE_NEW_PROCESS_GROUP
        subprocess.Popen(cmd, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
    else:
        # Linux/macOS 上启动新进程
        subprocess.Popen(cmd, start_new_session=True)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The function launches an external Python worker via subprocess on both Windows and non-Windows platforms, but the file provides no docstring, comment for users, confirmation prompt, or visible disclosure that a separate process will be started. The existing comments are implementation-focused and not user-facing, so this safety-relevant action lacks warning within the code file.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · model/scripts/video_interface.py (reported line 23)May include surrounding context.

python
subprocess.Popen(cmd, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
    else:
        # Linux/macOS 上启动新进程
        subprocess.Popen(cmd, start_new_session=True)
        
    return f"[*] 任务已提交: {prompt}"

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill documentation states that a result page will automatically open in the browser after task completion, but it does not clearly warn the user about this side effect or describe any validation around the opened URL. Automatic browser launch can surprise users, trigger unintended external navigation, and increase exposure if the generated page or target URL is unsafe or influenced by untrusted content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The activation condition requires the exact Chinese prefix '生成视频:', which imposes a specific language requirement in natural-language behavior. There is no indication of user opt-in, alternative language support, or documented justification for restricting activation to this locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

Comments and user-facing print messages are consistently written in Chinese, with no indication that the skill supports other languages or that Chinese is a required locale. This can violate a language/locale policy when the skill imposes a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified as requests>=2.25.1, which allows any newer version to be installed without guaranteeing a reviewed, fixed, or reproducible release. This creates supply-chain and patch-management risk because different environments may resolve to different versions, including versions with known vulnerabilities or breaking changes.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.25.1

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

The manifest references requests without pinning to a known-safe version, while the package has multiple published advisories across versions. Because resolution is uncontrolled beyond a minimum version, installations may pull a release affected by credential leakage, TLS/verification, or other security issues depending on the environment and time of install.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
hooks.js:11