Back to skill

Security audit

TubeScribe

Security checks for vulnerabilities and agentic risk

Overview

TubeScribe is coherent for YouTube summaries, but it warrants Review because it starts a tool-capable background workflow and can install persistent executable dependencies from the internet without strong verification.

Review before installing. Prefer installing dependencies yourself through trusted package managers, avoid the standalone/latest-download setup path unless you accept the supply-chain risk, and be aware that YouTube text and comments are untrusted content processed by a tool-capable agent. Generated transcripts and audio are saved locally under your user account.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/setup.py:372
Finding

Unverified Remote Executable Download and Installation

Content
View full analysis
bool: """ Install yt-dlp standalone binary. Installation location: ~/.openclaw/tools/yt-dlp/yt-dlp """ import platform import urllib.request existing = find_ytdlp() if existing: print(f" ℹ️ yt-dlp already installed at {existing}") return True tools_dir = os.path.expanduser("~/.openclaw/tools/yt-dlp") os.makedirs(tools_dir, exist_ok=True) system = platform.system().lower() machine = platform.machine().lower() base_url = "https://github.com/yt-dlp/yt-dlp/releases/latest/download" if system == "darwin": binary_name = "yt-dlp_macos" elif system == "linux": if machine == "aarch64": binary_name = "yt-dlp_linux_aarch64" else: binary_name = "yt-dlp_linux" else: print(f" ❌ Unsupported platform: {system}/{machine}") print(f" Try: pip install yt-dlp") return False url = f"{base_url}/{binary_name}" download_path = os.path.join(tools_dir, "yt-dlp") try: print(f" → Downloading yt-dlp...") urllib.request.urlretrieve(url, download_path) os.chmod(download_path, 0o755) print(f" ✅ yt-dlp installed to {download_path}") return True ``` A similar issue exists in `scripts/setup.py:253-339`, where a Pandoc release archive is downloaded and its extracted binary is made executable without validating a trusted checksum or signature. ### Technical Analysis The setup process retrieves a native executable through the mutable GitHub `latest/download` endpoint, writes it into a persistent tools directory, and immediately grants executable permissions. It does not verify a cryptographic digest, release signature, provenance attestat ...[truncated 1800 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Error
Location
scripts/setup.py:437
Finding

Unpinned Python Packages Are Installed and Executed During Setup

Content
View full analysis
bool: """Install mlx-audio in a dedicated venv at ~/.openclaw/tools/mlx-audio/. Only works on Apple Silicon (requires MLX framework). Creates a Python venv, installs mlx-audio + dependencies. """ import platform if not is_apple_silicon(): print(" ❌ mlx-audio requires Apple Silicon (M1/M2/M3/M4)") print(" Use Kokoro TTS (PyTorch) instead.") return False mlx_dir = os.path.expanduser("~/.openclaw/tools/mlx-audio") venv_dir = os.path.join(mlx_dir, ".venv") try: os.makedirs(mlx_dir, exist_ok=True) python_candidates = [ "/usr/local/bin/python3.12", "/opt/homebrew/bin/python3.12", "/opt/homebrew/bin/python3.13", sys.executable, ] python_bin = None for p in python_candidates: if os.path.exists(p): python_bin = p break if not python_bin: print(" ❌ No suitable Python found") return False if not os.path.exists(venv_dir): print(f" → Creating venv with {os.path.basename(python_bin)}...") subprocess.run([python_bin, "-m", "venv", venv_dir], check=True) venv_pip = os.path.join(venv_dir, "bin", "pip") venv_python = os.path.join(venv_dir, "bin", "python3") print(" → Installing mlx-audio (this may take a minute)...") subprocess.run( [venv_pip, "install", "--quiet", "mlx-audio", "misaki", "num2words", "spacy", "espeakng_loader"], check=True ) ``` The same pattern occurs in `scripts/setup.py:551-594`: ```python subprocess.run( [venv_pip, "install", "--quiet", "kokoro", "soundfile", "torc ...[truncated 1943 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:84
Finding

Untrusted YouTube Content Is Passed to a Tool-Capable Sub-Agent Without Prompt-Injection Isolation

Content
View full analysis
**` --- 2. Video info block — Channel, Date, Duration, URL (clickable). Empty line between each field. --- 3. `## **Participants**` — table with bold headers: ``` | **Name** | **Role** | **Description** | |----------|----------|-----------------| ``` --- 4. `## **Summary**` — 3-5 paragraphs of prose --- 5. `## **Key Quotes**` — 5 best with clickable YouTube timestamps. ``` The data read by the sub-agent is assembled from external content in `scripts/tubescribe.py:545-571`: ```python source_data = { "metadata": { "url": url, "video_id": video_id, "title": metadata["title"], "channel": metadata["channel"], "upload_date": metadata["upload_date"], "duration": metadata["duration"], "duration_string": metadata["duration_string"], "view_count": metadata.get("view_count", 0), "description": metadata["description"], }, "segments": segments, "comments": comments if comments else [], "stats": { "segment_count": len(segments), "word_count": word_count, "comment_count": len(comments) if comments else 0, } } source_path = f"{temp_dir}/tubescribe_{video_id}_source.json" output_path = f"{temp_dir}/tubescribe_{video_id}_output.md" w ...[truncated 2526 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (51)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill description omits or downplays material behaviors such as comment collection, queue management, standalone audio generation, and reliance on separate scripts for core processing. Behavior-description mismatches reduce informed consent and make it easier for a user or orchestrator to trigger handling of third-party content or background processing they did not expect.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The skill description omits or downplays material behaviors such as comment collection, queue management, standalone audio generation, and reliance on separate scripts for core processing. Behavior-description mismatches reduce informed consent and make it easier for a user or orchestrator to trigger handling of third-party content or background processing they did not expect.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
80% confidence
Finding

A configuration option to remove temporary files, especially described broadly as removing /tmp content, is risky if cleanup logic is implemented unsafely or with attacker-influenced paths. In a skill that shells out and processes filenames/IDs derived from external inputs, improper cleanup can become destructive file deletion.

Content

Scanner excerpt · SKILL.md (reported line 261)May include surrounding context.

md
| Option | Default | Description |
|--------|---------|-------------|
| `processing.subagent_timeout` | `600` | Seconds for sub-agent (increase for long videos) |
| `processing.cleanup_temp_files` | `true` | Remove /tmp files after completion |

### Comment Options
| Option | Default | Description |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
90% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/config.py (reported line 74)May include surrounding context.

python
# Processing settings
    "processing": {
        "subagent_timeout": 600,        # Seconds for sub-agent processing
        "cleanup_temp_files": True,     # Remove /tmp files after completion
    },
    
    # Comments settings

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · CHANGELOG.md (reported line 22)May include surrounding context.

md
- **CSS-based XSS in HTML writer** — added `style` attribute stripping alongside existing `on*` event handler removal

### Fixed
- **`is_processing()` had write side-effects** — split into read-only `is_processing()` and separate `clear_stale_current()` for stale entry cleanup
- **Duplicate `tempfile` import** — removed redundant local import in `generate_builtin_audio` (already imported at module level)
- **Silent fallthrough for unknown doc formats** — `convert_to_document` now warns and falls back to markdown instead of silently returning raw path
- **`prompt_yn` crash in non-interactive mode** — `input()` now catches `EOFError`/`KeyboardInterrupt` and returns `False`

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
60% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 46)May include surrounding context.

md
**What setup.py does:** Checks if recommended tools are present (`summarize`, `pandoc`, `ffmpeg`, TTS engine) and offers to install any missing ones. It only downloads from official sources (Homebrew, PyPI, GitHub releases). You can skip any install — the skill works without them using macOS built-in TTS and HTML fallback.

**What setup.py does NOT do:** It does not upload data, contact unknown hosts, or modify system files outside `~/.openclaw/tools/` and `~/.tubescribe/`.

## Output Example

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill invokes shell commands, reads and writes files, uses environment-based paths, and performs network access, but it declares no explicit tool scope or permissions boundary. That makes the effective capability set much broader than what a caller or platform can safely reason about, increasing the chance of over-privileged execution and accidental misuse.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The activation guidance is broad enough that ordinary requests involving YouTube links or summarization could trigger a high-capability workflow with shell, file, background processing, and network behavior. Over-broad triggering increases the chance of unexpected execution on untrusted URLs or unnecessary processing of third-party content.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The documentation says the sub-agent will make no network calls beyond YouTube, yet the setup path contemplates downloading a yt-dlp binary. Contradictory operational guarantees are dangerous because they can cause operators to trust a network boundary that the skill does not actually enforce.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The workflow persists generated documents and audio summaries under a fixed user Documents path, potentially retaining transcripts, quotes, comments, and derived audio longer than the user expects. For potentially sensitive video content, persistent local artifacts increase exposure to other local users, backups, indexing, or later unintended disclosure.

Content

Scanner excerpt · SKILL.md (reported line 133)May include surrounding context.


  1. ## **Full Transcript** — merge segments, speaker labels, clickable timestamps

Step 4: Create DOCX

Clean the title for filename (remove special chars), then:

bash
pandoc <output_path> -o ~/Documents/TubeScribe/<safe_title>.docx

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The configuration sets mlx_audio.lang_code to a with the description 'a=US English,' which establishes a specific locale by default. The file does not indicate user opt-in, choice, or a region-specific justification, making this a natural-language locale policy concern.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill includes a software acquisition path for yt-dlp, including downloading a standalone binary into a tools directory. Introducing install/download capability materially increases supply-chain and remote code execution risk, especially when the skill otherwise presents itself as a summarization workflow rather than a software bootstrapper.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

This builds Python code with an f-string and executes it via python -c, using import_name derived from package metadata (KOKORO_DEPS). If that mapping is modified or made attacker-controlled elsewhere, it becomes arbitrary Python code execution during setup checks. In a setup script that users are encouraged to run locally, this context makes code injection especially dangerous.

Content

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

python
"""Check if a Python package is installed in system Python."""
    import_name = import_name or package
    try:
        result = subprocess.run(
            [sys.executable, "-c", f"import {import_name}"],
            capture_output=True, timeout=10
        )

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/setup.py (reported line 99)May include surrounding context.

python
# 2. Check shared ML env
    if os.path.exists(ml_env_python):
        try:
            result = subprocess.run(
                [ml_env_python, "-c", "import torch, soundfile, numpy, huggingface_hub"],
                capture_output=True, timeout=10
            )

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/setup.py (reported line 112)May include surrounding context.

python
venv_python = os.path.join(kokoro_dir, ".venv", "bin", "python")
    if os.path.exists(venv_python):
        try:
            result = subprocess.run(
                [venv_python, "-c", "from kokoro import KPipeline"],
                capture_output=True, timeout=10, cwd=kokoro_dir
            )

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/setup.py (reported line 138)May include surrounding context.

python
python_path, kokoro_dir = get_python_for_kokoro()
    if python_path and kokoro_dir:
        try:
            result = subprocess.run(
                [python_path, "-c", "from kokoro import KPipeline; print('ok')"],
                capture_output=True, timeout=10, cwd=kokoro_dir
            )

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/setup.py (reported line 237)May include surrounding context.

python
"""Install something with Homebrew."""
    print(f"  → Installing {name}...")
    try:
        subprocess.run(["brew", "install", formula], check=True)
        print(f"  ✅ {name} installed!")
        return True
    except subprocess.CalledProcessError:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/setup.py (reported line 271)May include surrounding context.

python
version = None
    try:
        req = urllib.request.Request(
            "https://api.github.com/repos/jgm/pandoc/releases/latest",
            headers={"Accept": "application/vnd.github.v3+json", "User-Agent": "TubeScribe-Setup"}
        )
        with urllib.request.urlopen(req, timeout=10) as resp:

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/setup.py (reported line 473)May include surrounding context.

python
print("  ❌ No suitable Python found")
            return False
        
        # Create venv
        if not os.path.exists(venv_dir):
            print(f"  → Creating venv with {os.path.basename(python_bin)}...")
            subprocess.run([python_bin, "-m", "venv", venv_dir], check=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 · scripts/setup.py (reported line 476)May include surrounding context.

python
# Create venv
        if not os.path.exists(venv_dir):
            print(f"  → Creating venv with {os.path.basename(python_bin)}...")
            subprocess.run([python_bin, "-m", "venv", venv_dir], check=True)
        
        venv_pip = os.path.join(venv_dir, "bin", "pip")
        venv_python = os.path.join(venv_dir, "bin", "python3")

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/setup.py (reported line 583)May include surrounding context.

python
# Create venv
        if not os.path.exists(venv_dir):
            print(f"  → Creating venv with {os.path.basename(python_bin)}...")
            subprocess.run([python_bin, "-m", "venv", venv_dir], check=True)
        
        venv_pip = os.path.join(venv_dir, "bin", "pip")
        venv_python = os.path.join(venv_dir, "bin", "python3")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
91% confidence
Finding

This installs packages from PyPI at setup time into a persistent virtual environment, executing package installation logic from the network without pinning versions or verifying hashes. A supply-chain compromise, dependency confusion, or malicious upstream release could result in arbitrary code execution on the user's machine.

Content

Scanner excerpt · scripts/setup.py (reported line 483)May include surrounding context.

python
# Install mlx-audio + deps
        print("  → Installing mlx-audio (this may take a minute)...")
        subprocess.run(
            [venv_pip, "install", "--quiet", "mlx-audio", "misaki", "num2words",
             "spacy", "espeakng_loader"],
            check=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 · scripts/setup.py (reported line 529)May include surrounding context.

python
# Verify it works
        print("  → Verifying mlx-audio...")
        result = subprocess.run(
            [venv_python, "-c", "from mlx_audio.tts.generate import generate_audio; print('OK')"],
            capture_output=True, text=True, timeout=30
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

Like the mlx-audio install path, this performs network package installation into a persistent venv with unpinned dependencies and no integrity verification. Because pip installs can run arbitrary build/install code and fetch compromised releases, this creates a real supply-chain execution risk during setup.

Content

Scanner excerpt · scripts/setup.py (reported line 590)May include surrounding context.

python
# Install kokoro + deps (~500MB for PyTorch)
        print("  → Installing Kokoro + PyTorch (this may take a few minutes)...")
        subprocess.run(
            [venv_pip, "install", "--quiet", "kokoro", "soundfile", "torch",
             "misaki", "num2words", "spacy"],
            check=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 · scripts/setup.py (reported line 598)May include surrounding context.

python
# Verify it works
        print("  → Verifying Kokoro...")
        result = subprocess.run(
            [venv_python, "-c", "from kokoro import KPipeline; print('OK')"],
            capture_output=True, text=True, timeout=30
        )

Static analysis

No suspicious patterns detected.