Back to skill

Security audit

YouTube Download

Security checks for vulnerabilities and agentic risk

Overview

This YouTube downloader is coherent, but it automatically installs or updates executable dependencies and can use browser cookies, which deserve review before installation.

Install only if you are comfortable with the skill changing your user-level Python/yt-dlp installation during normal use. Prefer running with `--skip-update`, preinstalling a trusted pinned yt-dlp version yourself, and avoiding `--cookies-from-browser` unless you explicitly need authenticated video access and trust the runtime handling your browser session cookies.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (1)

T08 · Insecure Dependencies

Error
Location
scripts/youtube_download.py:24
Finding

Unpinned Dependency Installation and Automatic Code Updates

Content
View full analysis

Vulnerability Details

File Location: scripts/youtube_download.py:24-25, 88-104
Vulnerability Type: Unpinned third-party dependency installation and automatic executable updates
Risk Level: High

Vulnerable Code

python
def pip_install_or_upgrade() -> None:
    run([sys.executable, "-m", "pip", "install", "--user", "-U", "yt-dlp"])
python
def ensure_yt_dlp(*, skip_update: bool) -> Command:
    yt_dlp = find_yt_dlp()
    if yt_dlp is None:
        print("yt-dlp not found; installing latest yt-dlp with pip.", flush=True)
        pip_install_or_upgrade()
        yt_dlp = find_yt_dlp(prefer_user=True)

    if yt_dlp is None:
        raise SystemExit(
            "yt-dlp installation completed, but yt-dlp was not found as an executable "
            "or importable Python module."
        )

    if skip_update:
        return yt_dlp

    update = subprocess.run([*yt_dlp, "-U"], text=True)
    if update.returncode != 0:
        print("yt-dlp self-update failed or is disabled; upgrading with pip instead.", flush=True)
        pip_install_or_upgrade()
        yt_dlp = find_yt_dlp(prefer_user=True) or yt_dlp

    return yt_dlp

Technical Analysis

The helper installs the latest available yt-dlp release from the package index when the dependency is missing. It also attempts to update an existing executable during every normal run unless the user supplies --skip-update. If self-update fails, it performs another unpinned pip upgrade.

Neither installation path enforces a reviewed version, artifact hash, signature, lock file, or trusted immutable package source. The code executed by the Skill can therefore change after the Skill itself has been audited. This creates a supply-chain boundary in which compromise of the package release, package index, distribution channel, or self-update mechanism could introduce attacker-controlled code.

The use of an argv list prevents ...[truncated 1686 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin yt-dlp to a specifically reviewed version instead of using an unconstrained -U installation.
  2. Verify downloaded artifacts with approved cryptographic hashes or trusted signatures. Use a lock file with hash enforcement where supported.
  3. Remove automatic updates from the routine download path. Make dependency upgrades an explicit maintenance operation requiring user approval.
  4. Install the dependency in a dedicated virtual environment rather than modifying the user's general Python environment.
  5. Configure pip to use an explicitly trusted package repository and reject unexpected alternate indexes.
  6. After an approved upgrade, rerun security review and functional tests before making the version available to normal Skill execution.
  7. If self-update must remain available, require an explicit update flag, validate the update source and artifact, and display the current and target versions before proceeding.
  8. Run media downloads with the minimum required filesystem access. Avoid exposing browser cookies unless necessary, and prefer a narrowly scoped cookie file when authentication is required.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (11)

Self-Modification

High
Category
Rogue Agent
Confidence
95% confidence
Finding

The skill instructs the helper to install or upgrade yt-dlp automatically via pip or self-update before use. Self-modifying behavior is dangerous because it pulls and executes newly fetched code at runtime, bypassing version pinning and review, and can introduce supply-chain compromise or unexpected behavior changes.

Content

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

md
Use `python3` on most Linux/macOS systems. Use `py -3` or `python` on Windows when that is the configured Python launcher.

The helper checks for `yt-dlp`, installs it with `<python> -m pip install --user -U yt-dlp` if missing, tries `yt-dlp -U`, falls back to pip upgrade when self-update is unavailable, then runs the download. If a pip-installed executable is not on `PATH`, the helper searches common per-user script directories and falls back to `python -m yt_dlp`.

## Workflow

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
79% confidence
Finding

The skill recommends using --cookies-from-browser to access private or age-restricted content, which can cause the tool to read authentication cookies from the user's browser profile. Although this is a legitimate yt-dlp feature, in an agent context it expands access to sensitive browser-stored credentials and session material, creating a real risk of unauthorized data exposure or abuse if mishandled.

Content

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

t MP3 audio:

bash
python3 youtube-download/scripts/youtube_download.py "URL" --audio --audio-format mp3

Save subtitles and thumbnail:

bash
python3 youtube-download/scripts/youtube_download.py "URL" --subtitles --thumbnail

Use browser cookies for private, member-only, age-restricted, or region-sensitive videos:

bash
python3 youtube-download/scripts/youtube_download.py "URL" --cookies-from-browser chrome

Pass extra yt-dlp flags:

bash
python3 youtube-download/scripts/youtube_download.py "URL" -- --write-info-json --write-comments

Notes

  • yt-dlp -U can automatically update official standalone builds. Some package-managed installs disable self-update; use pip upgrade as the fallback.
  • The helper is platform-neutral: it looks for yt-dlp, yt-dlp.exe, or yt-dlp.cmd, then checks user install paths such as Python Scripts on Windows and user bin directories on Linux/macOS.
  • Avoid downloading copyrighted material unless the user has rights or

Self-Modification

High
Category
Rogue Agent
Confidence
94% confidence
Finding

The notes explicitly recommend yt-dlp self-update and pip upgrade fallback, reinforcing runtime self-modification as normal behavior. In an agent skill, this increases risk because execution depends on fetching mutable external code during task handling rather than on audited, fixed dependencies.

Content

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

md
## Notes

- `yt-dlp -U` can automatically update official standalone builds. Some package-managed installs disable self-update; use pip upgrade as the fallback.
- The helper is platform-neutral: it looks for `yt-dlp`, `yt-dlp.exe`, or `yt-dlp.cmd`, then checks user install paths such as Python `Scripts` on Windows and user `bin` directories on Linux/macOS.
- Avoid downloading copyrighted material unless the user has rights or permission.
- For login-required content, prefer `--cookies-from-browser` or `--cookies FILE` instead of asking the user for credentials.

Self-Modification

High
Category
Rogue Agent
Confidence
97% confidence
Finding

The code performs self-modifying behavior by updating yt-dlp at runtime, either through yt-dlp -U or pip fallback. Self-update inside an agent skill is hazardous because it changes executable behavior outside normal deployment controls and expands the attack surface to package/update infrastructure.

Content

Scanner excerpt · scripts/youtube_download.py (reported line 109)May include surrounding context.

python
update = subprocess.run([*yt_dlp, "-U"], text=True)
    if update.returncode != 0:
        print("yt-dlp self-update failed or is disabled; upgrading with pip instead.", flush=True)
        pip_install_or_upgrade()
        yt_dlp = find_yt_dlp(prefer_user=True) or yt_dlp

YARA rule 'info_stealer': Information stealer patterns (credential harvesting, browser data theft) [malware]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).

Content

Scanner excerpt · scripts/youtube_download.py (reported line 179)May include surrounding context.

python
"--subtitle-languages",
        default="en.*,zh.*",
        help="Subtitle language selector for --subtitles.",
    )
    parser.add_argument("--thumbnail", action="store_true", help="Write video thumbnail.")
    parser.add_argument("--cookies", help="Path to a Netscape-format cookies file.")
    parser.add_argument(
        "--cookies-from-browser",
        help="Browser name for yt-dlp cookies, for example chrome, safari, firefox, edge.",
    )
    parser.add_argument(
        "--skip-update",
        action="store_true",
        help="Do not update yt-dlp before downloading.",
    )
    parser.add_argument(
        "extra",
        nargs=argparse.REMAINDER,
        help="Additional yt-dlp arguments after '--'.",
    )

    args = parser.parse_args()
    if args.extra and args.extra[0] == "--":
        args.extra = args.extra[1:]
    return args


def main() -> None:
    args = parse_args()
    yt_dlp = ensure_yt_dlp(skip_update=args.skip_update)
    cmd = build_command(args

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill invokes shell and environment-capable operations but does not declare any explicit tool scope or restrictions. That weakens security boundaries because an agent may execute installation, update, and download commands without a narrowly defined permission model, increasing the chance of unintended command execution or misuse.

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

python
def run(cmd: Command, *, check: bool = True) -> subprocess.CompletedProcess[str]:
    print("+ " + " ".join(cmd), flush=True)
    return subprocess.run(cmd, text=True, check=check)


def pip_install_or_upgrade() -> None:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script installs or upgrades yt-dlp automatically via pip, modifying the local Python user environment without an explicit confirmation or warning. In a skill/agent setting this is dangerous because normal use of the tool causes side effects on the host and introduces supply-chain exposure from network-fetched code.

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

python
def yt_dlp_module_available() -> bool:
    return subprocess.run(
        [sys.executable, "-c", "import yt_dlp"],
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
92% confidence
Finding

The script automatically invokes yt-dlp self-update, which executes code fetched from an external package/update channel without an explicit trust boundary or consent step. In an agent skill context, silent update behavior increases supply-chain risk and can unpredictably modify the runtime before processing user requests.

Content

Scanner excerpt · scripts/youtube_download.py (reported line 107)May include surrounding context.

python
if skip_update:
        return yt_dlp

    update = subprocess.run([*yt_dlp, "-U"], text=True)
    if update.returncode != 0:
        print("yt-dlp self-update failed or is disabled; upgrading with pip instead.", flush=True)
        pip_install_or_upgrade()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill accepts a cookie file path and can import cookies directly from a browser without presenting a privacy or credential-handling warning. Browser cookies and exported cookie files may grant access to authenticated sessions, so exposing these options in an agent skill raises the risk of unintended credential misuse or sensitive-session exfiltration.

Content

No source excerpt is available for this finding.