Back to skill

Security audit

Video No Subtitle Transcribe

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local video transcription fallback, with notable but disclosed risks around model download, proxy handling, and an optional third-party browser fallback.

Before installing, be comfortable with a 483MB model being downloaded to your home directory, yt-dlp fetching media for URLs you provide, and proxy settings being read automatically. Do not use the iiilab browser fallback for private, unlisted, sensitive, or client-owned videos unless you explicitly approve sharing the URL with that third party. Prefer specifying the correct --lang value and avoid authenticated proxy URLs where local process listings may expose them.

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)

T08 · Insecure Dependencies

Warning
Location
scripts/transcribe_video.py:17
Finding

Downloaded Whisper model is not cryptographically authenticated

Content
View full analysis
{MODEL_BIN}", flush=True) import urllib.request part = MODEL_BIN + ".part" req = urllib.request.Request(MODEL_URL) with urllib.request.urlopen(req, timeout=900) as r, open(part, "wb") as f: while True: chunk = r.read(1 << 20) if not chunk: break f.write(chunk) os.rename(part, MODEL_BIN) got = os.path.getsize(MODEL_BIN) if got != MODEL_EXPECTED_BYTES: print(f"[model] WARNING: {got} != expected {MODEL_EXPECTED_BYTES}", flush=True) print(f"[model] ready ({got} bytes)", flush=True) ``` The resulting artifact is subsequently loaded at line 113: ```python model = WhisperModel(MODEL_DIR, device="cpu", compute_type="int8") ``` ### Technical Analysis The script treats an exact file length as proof that the model is intact. File size does not authenticate content: an attacker who can modify the remote artifact or its upstream distribution can produce a different file with the same length. The post-download validation is weaker still. If the downloaded file has an unexpected size, the s ...[truncated 1761 chars]
Remediation
View remediation
" def sha256_file(path): digest = hashlib.sha256() with open(path, "rb") as source: for chunk in iter(lambda: source.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() if sha256_file(part) != MODEL_SHA256: os.remove(part) raise RuntimeError("Downloaded model failed SHA-256 verification") os.replace(part, MODEL_BIN) ``` ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/transcribe_video.py:25
Finding

Credential-bearing proxy URL is exposed through child process arguments

Content
View full analysis
环境变量 HTTPS_PROXY/HTTP_PROXY > OpenClaw 配置(~/.openclaw/openclaw.json,国内环境常用)。 """ if explicit: return explicit for var in ("HTTPS_PROXY", "https_proxy", "HTTP_PROXY", "http_proxy"): v = os.environ.get(var) if v: return v try: with open(os.path.expanduser("~/.openclaw/openclaw.json")) as f: cfg = json.load(f) return cfg.get("channels", {}).get("telegram", {}).get("proxy", "") except Exception: return "" ``` ```python def run_ytdlp(cmd, proxy=""): """跑 yt-dlp,返回 (returncode, stderr)。""" env = dict(os.environ) proxy = get_proxy(proxy) if proxy: env["HTTPS_PROXY"] = proxy env["HTTP_PROXY"] = proxy base = ["yt-dlp"] if proxy: base += ["--proxy", proxy] r = subprocess.run(base + cmd, env=env, capture_output=True, text=True) return r.returncode, r.stderr ``` ### Technical Analysis Proxy URLs can contain credentials, for example: ```text http://username:password@proxy.example:8080 ``` The script can obtain such a URL from the OpenClaw configuration or environment and then inserts the complete value into the `yt-dlp` argument vector through `["--proxy", proxy]`. Command-line arguments are commonly visible in process listings, monitoring agents, diagnostic tooling, and process metadata while the child process is active. Consequently, copying a configuration-derived credential into the command line unnecessarily increases its exposure. The script already sets `HTTPS_PROXY` and `HTTP_PROXY`, so adding the same secret to the child argument vector is redundant. A proxy passed directly to this script through its own `--proxy` option ma ...[truncated 1275 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/transcribe_video.py (reported line 68)May include surrounding context.

python
def run_ytdlp(cmd, proxy=""):
    """跑 yt-dlp,返回 (returncode, stderr)。"""
    env = dict(os.environ)
    proxy = get_proxy(proxy)
    if proxy:
        env["HTTPS_PROXY"] = proxy

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The trigger list contains broad phrases such as 'transcribe video' and 'whisper transcription' that are not tightly scoped to the advertised fallback condition of missing subtitles. Overbroad activation can cause the wrong skill to run in situations where safer, more appropriate, or less privacy-impacting flows should be used first, increasing the chance of unnecessary downloads, local processing, or third-party fallback usage.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The arguments section specifies zh as the default language, which implicitly forces a locale choice unless the user overrides it. The file does not state that the assistant should ask the user for language preference before using that default.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation makes a strong privacy claim ('no privacy leakage') even though the skill explicitly includes a browser fallback that sends the source YouTube URL to a third-party service. This can mislead users or downstream agents into using the fallback for sensitive or private content under false assumptions, resulting in unintended disclosure of viewing targets or client-owned URLs.

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 · scripts/transcribe_video.py (reported line 76)May include surrounding context.

python
base = ["yt-dlp"]
    if proxy:
        base += ["--proxy", proxy]
    r = subprocess.run(base + cmd, env=env, capture_output=True, text=True)
    return r.returncode, r.stderr

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The CLI forces a default language of zh unless the user overrides it. This is a natural-language locale choice imposed by default rather than selected by the user, which can violate language/locale policy when no explicit opt-in or neutral auto-detection is offered.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The usage example and argument table set --lang zh as the default, which steers the skill toward a specific language/locale by default. The README does not present this as an opt-in choice or explain a region-specific reason for enforcing Chinese as the default behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

The script accesses ~/.openclaw/openclaw.json to obtain proxy settings, which is a form of reading potentially sensitive local configuration. Although the helper docstring mentions this behavior, the main user-facing flow does not clearly disclose that invoking the script may inspect that file automatically when no proxy is passed.

Content

No source excerpt is available for this finding.