Back to skill

Security audit

youtube-transcript

Security checks for vulnerabilities and agentic risk

Overview

The skill has a clear YouTube transcript purpose, but it lets user-supplied inputs drive broad network fetching and arbitrary file writes without enough containment.

Review this before installing. Use it only with trusted YouTube URLs, avoid letting untrusted content choose the output path, and prefer stdout or a dedicated transcript directory. The package does not show malicious intent, but it should add URL allowlisting and safe output-file handling before being treated as low-risk.

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)

T09 · Insecure Skill Coding Practices

Warning
Location
yt_transcript.py:13
Finding

Unrestricted URL Enables Unintended Network Requests

Content
View full analysis
str: """Download auto-generated subtitles and return the VTT content.""" with tempfile.TemporaryDirectory() as tmp: out = Path(tmp) / "sub" subprocess.run( [ "yt-dlp", "--write-auto-sub", "--write-sub", "--skip-download", "--sub-lang", lang, "-o", str(out), url, ], check=True, capture_output=True, text=True, ) ``` ### Technical Analysis The command-line URL is passed directly to the network-capable `yt-dlp` program without validating its scheme, hostname, port, or resolved destination. Although the Skill is documented as accepting YouTube URLs, the implementation does not enforce that restriction. `subprocess.run` uses an argument list and does not enable `shell=True`, so this is not a shell-command injection vulnerability. The risk instead arises because `yt-dlp` supports multiple websites and generic URL extraction. An attacker who can influence the URL given to the Agent may cause the host running the Skill to contact a destination outside the declared YouTube service. This could include attacker-controlled servers or services reachable only from the Agent's network environment. Redirect behavior may also undermine a hostname-only check unless redirect destinations and resolved addresses are constrained. ### Attack Path 1. An attacker supplies a crafted non-YouTube URL while requesting transcript extraction. 2. The Agent follows the documented workflow and invokes `yt_transcript.py` with that URL. 3. `download_subs()` forwards the URL to `yt-dlp` without validation. 4. `yt-dlp` attempts to a ...[truncated 941 chars]
Remediation
View remediation
str: parsed = urlparse(value) host = (parsed.hostname or "").lower().rstrip(".") if parsed.scheme != "https" or host not in ALLOWED_HOSTS: raise ValueError("Only HTTPS YouTube URLs are permitted") if parsed.username is not None or parsed.password is not None: raise ValueError("URL credentials are not permitted") return value ``` ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
yt_transcript.py:101
Finding

Caller-Controlled Output Path Can Overwrite Arbitrary Writable Files

Content
View full analysis
Remediation
View remediation
Path: OUTPUT_ROOT.mkdir(parents=True, exist_ok=True) root = OUTPUT_ROOT.resolve() target = (root / name).resolve() if target == root or root not in target.parents: raise ValueError("Output path must remain inside the transcript directory") if target.exists() or target.is_symlink(): raise FileExistsError("Refusing to overwrite an existing destination") return target target = safe_output_path(args.output) with target.open("x", encoding="utf-8") as output_file: output_file.write(transcript) ``` ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill invokes a Python script, depends on yt-dlp, and explicitly describes reading and writing transcript files, which implies shell execution plus filesystem access. Because the manifest declares no permissions or allowed-tools, the runtime scope is under-specified and can allow broader-than-intended capabilities, reducing reviewability and increasing the chance of misuse or unsafe invocation paths.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The activation text is fairly broad: it triggers when a user provides a YouTube URL or wants a transcript from a podcast, interview, or talk, which could match many general summarization or content-processing requests. Over-broad routing can cause the skill to be selected in situations where shelling out to external tools and writing files is unnecessary, expanding exposure to network, shell, and file operations beyond what the user likely intended.

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 · yt_transcript.py (reported line 17)May include surrounding context.

python
"""Download auto-generated subtitles and return the VTT content."""
    with tempfile.TemporaryDirectory() as tmp:
        out = Path(tmp) / "sub"
        subprocess.run(
            [
                "yt-dlp",
                "--write-auto-sub",

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function default lang: str = "en" establishes English as the implicit language, and the CLI help at L086 repeats that English is the default. This is a natural-language locale policy concern because the skill applies a specific language unless the user overrides it, rather than prompting or detecting preference.

Content

No source excerpt is available for this finding.