T09 · Insecure Skill Coding Practices
- Location
model/scripts/veo_worker.py:65- Finding
Disclosure of an Arbitrary OpenClaw Provider API Key to an External Service
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This video-generation skill is mostly purpose-aligned, but it handles credentials and remote results in ways users should review before installing.
Install only if you are comfortable with a Wanjie-hosted service receiving your video prompts and a configured API key. Use a dedicated low-quota Wanjie key, verify it is the only or explicitly selected credential, and review or disable the automatic browser opening, runtime pip install, background worker, logs, and any scheduled task behavior before use.
model/scripts/veo_worker.py:65Disclosure of an Arbitrary OpenClaw Provider API Key to an External Service
model/scripts/veo_worker.py:102Automatic Opening of an Unvalidated URL from Model-Controlled Output
model/scripts/video_interface.py:7Runtime Installation of an Unpinned Python Dependency
The script extracts the first URL from remote response text and immediately opens it on the host machine. Because the response is network-controlled, this creates a direct remote-to-local action channel that can drive users to phishing pages, malware delivery, or dangerous custom URI schemes without review.
The trigger instruction requires the user to input the Chinese phrase 生成视频:[您的视频描述], and the document provides no alternative language option or explanation that the skill is intentionally Chinese-only. This is a natural-language locale constraint that is not presented as an opt-in choice.
The README explicitly states that missing Python dependencies may be downloaded automatically once the environment has network access, but it does not provide a clear warning that running the skill can cause outbound network activity and modify the local environment. In an agent skill context, silent dependency installation increases supply-chain and change-management risk because users may trigger code execution without realizing packages will be fetched from external sources.
The trigger phrase is extremely broad: users are told to simply type a natural-language request like “生成视频:[提示词]”, while the skill also claims it intercepts instructions and automatically invokes background processing. Without clear boundaries, confirmation, or exclusion rules, normal conversation can unintentionally trigger task execution, causing unexpected API usage, background activity, and file/log generation.
The skill discloses persistent background monitoring, automatic dependency installation, log/file output, timeout cleanup, and creation of a Windows scheduled task, but does not provide meaningful user consent, scope limitation, or risk disclosure. This behavior increases the attack surface because it enables persistence-like execution, silent system changes, and possible leakage of prompts or generated content into logs and local files.
This code spawns a detached Python process to generate a video and only informs the user afterward that generation is happening in the background. There is no confirmation prompt, pre-execution disclosure, or inline warning before launching the subprocess, which is a safety-relevant operation for code files.
The script's comments, log messages, and result strings are written in Chinese, and the generated request content also appends Chinese text later in the file. There is no mechanism for user locale choice or opt-in, which violates the policy against forcing a specific language without user selection.
The script includes capability to open arbitrary URLs in the local system handler/browser, which can trigger navigation to attacker-controlled content or invocation of registered URI handlers. In an agent skill with no clearly declared permission model, this expands from simple browsing into local side effects driven by untrusted remote content.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
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 calls execute external commands. Without careful input validation, this enables command injection.
elif platform.system() == 'Darwin': # macOS
subprocess.Popen(['open', url])
else: # Linux
subprocess.Popen(['xdg-open', url])
def is_process_running(pid):
"""检查指定 PID 的进程是否在运行"""
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 如果没有 psutil,使用简单但有效的方法
import subprocess
if platform.system() == 'Windows':
res = subprocess.run(['tasklist', '/FI', f'PID eq {pid}'], capture_output=True, text=True)
return str(pid) in res.stdout
return True # 默认不删除锁,以防误删
The code reads an API key from a user home-directory configuration file without any visible permission boundary or user consent flow. In a skill context, accessing local secrets is sensitive because the skill can use credentials the user did not intend to expose to this specific component.
The code modifies the prompt by appending the Chinese phrase ',时长 {seconds} 秒', forcing a Chinese-language instruction into the model request regardless of user preference. This is a natural-language locale constraint with no opt-in or documented justification.
The script transmits user-supplied prompt content and model selection to an external API endpoint, authenticated with a locally sourced API key. External transmission is expected for API-backed functionality, but in the absence of declared permissions and data-handling notice, it is still a real confidentiality concern for prompts that may contain sensitive data.
}
print(f"[*] API 请求发送中... (Model: {model})", 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)
The script transmits user-supplied prompt content and model selection to an external API endpoint, authenticated with a locally sourced API key. External transmission is expected for API-backed functionality, but in the absence of declared permissions and data-handling notice, it is still a real confidentiality concern for prompts that may contain sensitive data.
}
print(f"[*] API 请求发送中... (Model: {model})", 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)
This code both installs packages at runtime and spawns a detached worker process, which changes the environment and execution model beyond a simple library-style helper. In the absence of explicit skill metadata justifying environment modification and background execution, this is risky because it hides side effects, complicates auditing, and increases the chance of abuse or persistence-like behavior.
Running pip automatically without a user-facing warning or confirmation is unsafe because it performs privileged environment changes and may execute untrusted installation-time code paths from dependency sources. Users and operators are denied the chance to review what will be installed, from where, and under which permissions.
Automatically invoking pip at runtime modifies the host environment without explicit user approval and executes package installation logic from configured package indexes. In a skill context, this can introduce supply-chain risk, unexpected code execution during install, and non-deterministic behavior if indexes or dependencies are tampered with.
importlib.import_module("requests")
except ImportError:
print("[*] 正在安装缺失依赖: requests...")
subprocess.check_call([sys.executable, "-m", "pip", "install", "requests"])
def trigger_veo_generation(prompt, model="veo3.1-fast", seconds=8):
# 在触发前确保环境就绪
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# 跨平台进程启动设置
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)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
subprocess.Popen(cmd, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)
else:
# Linux/macOS 上启动新进程
subprocess.Popen(cmd, start_new_session=True)
return f"[*] 任务已提交: {prompt},请在聊天窗口耐心等待结果通知。"
The file uses Chinese for comments, docstrings, print output, and the returned user-facing status message, with no indication that the user can choose another language. This creates a language-policy concern because the skill imposes a specific language/locale without documented opt-in or justification.
The dependency is specified as requests>=2.25.1, which allows installation of a wide range of versions and makes builds non-reproducible. This is dangerous because a vulnerable or unintended future release could be pulled in, and it also prevents reviewers from verifying exactly which version is used.
requests>=2.25.1
requests has multiple known advisories, and because the manifest does not pin a specific version, there is no reliable way to determine whether an affected release may be installed. This is risky because deployments may resolve to different versions over time, potentially introducing a known vulnerable package into the skill.
Detected: suspicious.dangerous_exec