fix(security): restrict youtube-audio to YouTube hostnames - #16
Conversation
The route handed a caller-supplied URL straight to yt_dlp, which falls back to its generic extractor for anything it doesn't recognize — that extractor can fetch essentially any web page server-side, an SSRF shape with no scheme/host restriction. The UI only ever offers "paste a YouTube URL" (screen.html), so add _is_youtube_url() and reject any request whose scheme isn't http/https or whose host isn't a real youtube.com/youtu.be hostname with 400, before yt_dlp ever sees the URL. Closes #14. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013Kh8gR75zYwFUT3crRoEbH
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This PR fixes an SSRF vulnerability in the youtube-audio endpoint (issue #14). The route previously passed caller-supplied URLs to yt_dlp without validation, allowing yt_dlp's generic extractor to fetch arbitrary pages server-side.
- SSRF guard (
_is_youtube_url) — Adds a whitelist-based hostname validator atroutes.py:1047-1066usingurlparse. Checks scheme (http/https) and hostname against a frozenset of known YouTube hostnames. Pure string validation, no network access. - Route guard — Applies
_is_youtube_urlas an early-return in theyoutube_audiohandler atroutes.py:6757-6758, returning 400 beforeyt_dlpever sees the URL. - Comprehensive tests — New
tests/test_youtube_audio_url.py(74 lines) covers valid YouTube URLs, non-YouTube hosts (including169.254.169.254cloud metadata), lookalike domains, userinfo confusion (youtube.com@evil.example), non-HTTP schemes, and malformed input. - Version bump and changelog —
plugin.jsonbumped to 1.8.3, security entry added toCHANGELOG.md.
Big Pickle (free) | 𝕏

The route handed a caller-supplied URL straight to yt_dlp, which falls
back to its generic extractor for anything it doesn't recognize — that
extractor can fetch essentially any web page server-side, an SSRF shape
with no scheme/host restriction. The UI only ever offers "paste a
YouTube URL" (screen.html), so add _is_youtube_url() and reject any
request whose scheme isn't http/https or whose host isn't a real
youtube.com/youtu.be hostname with 400, before yt_dlp ever sees the URL.
Closes #14.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com