# yt-dlp: Arbitrary Command Injection when using the `--netrc-cmd` option

yt-dlp's --netrc-cmd placeholder substitutes attacker-controlled netrc machine values from crafted URLs into a shell=True command, enabling arbitrary command injection.

- Payout: Research
- Severity: high
- Program: yt-dlp
- Found by: dxlerYT
- Disclosed: 2026-02-23
- CVE: CVE-2026-26331
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-g3gw-q23r-pgqm
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-g3gw-q23r-pgqm
- Tags: area:oss domain:oss impact:rce kind:research platform:ghsa sev:high tech:python technique:source-review vuln:command-injection vuln:rce

**Target:** --netrc-cmd option / netrc_cmd API in yt-dlp CLI and Python library
**Root cause:** The netrc 'machine' value is dynamically derived from the site hostname in GetCourseRuIE, TeachableIE and TeachableCourseIE (wildcard subdomain matches allowed), and is substituted into the --netrc-cmd placeholder which is executed via subprocess.Popen with shell=True, so shell metacharacters in the hostname are interpreted.
**Steps:**
1. Identify that --netrc-cmd with a `{}` placeholder substitutes the netrc machine value into a shell command run with shell=True.
2. Craft a URL whose hostname contains shell metacharacters and matches a vulnerable extractor's wildcard subdomain pattern, e.g. `https://;echo pwned>&2;#.getcourse.ru/video`.
3. Run `yt-dlp --netrc-cmd "echo {}" "https://;echo pwned>&2;#.getcourse.ru/video"`.
4. Observe the machine value `;echo pwned>&2;` is substituted and the injected command executes (`pwned` printed).
**How found:** Noticed that four extractors source the netrc machine value dynamically from the hostname, three of which allow wildcard subdomain matches, and that this value flows into a shell=True command via the placeholder.
**Exploitation:** Attacker hosts a page with an inconspicuous URL and legitimate-looking media that serves an HTTP redirect to the crafted URL; yt-dlp's generic extractor follows the redirect and matches the vulnerable extractor, causing the injected shell command to run on the victim's machine.
**Escalation:** Generic extractor following HTTP redirects lets any innocuous URL be redirected to a crafted URL matching a vulnerable extractor, widening the attack surface beyond direct user input.
**Insight:** When a tool substitutes externally-derived values (hostnames, redirect targets) into a shell command template, check every extractor that derives that value from user-controllable input rather than a hardcoded constant, and check whether wildcard matching permits metacharacters.

## Proof of concept (copied exactly from the original report)

**yt-dlp command injecting shell via crafted URL**

```
> yt-dlp --netrc-cmd "echo {}" "https://;echo pwned>&2;#.getcourse.ru/video"
[GetCourseRu] Executing command: echo getcourseru
WARNING: [GetCourseRu] Failed to parse .netrc: bad toplevel token 'getcourseru' (-, line 2)
[GetCourseRu] Extracting URL: https://;echo pwned>&2;#.getcourse.ru/video
[GetCourseRu] Executing command: echo ;echo pwned>&2;
pwned
[GetCourseRu] No authenticators for ;echo pwned>&2;
[GetCourseRu] video: Downloading webpage
```

