docs: document the SSRF guard's connect-time coverage limitations

The connect-time getaddrinfo guard added for redirect/rebinding SSRF covers
only the download subprocess: metadata extraction runs in the main process
(where a process-wide guard would reject the server's own HOST=0.0.0.0 bind),
and native curl_cffi/libcurl resolution used by --impersonate bypasses Python's
socket module. Record both in url_guard's docstring and at the extraction site
so the boundary is explicit; network isolation remains the backstop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Alex Shnitman
2026-07-21 07:41:01 +03:00
parent 1b02a99510
commit 13cb65d931
2 changed files with 17 additions and 2 deletions
+12 -2
View File
@@ -13,8 +13,18 @@ This module provides two layers:
covers redirects, DNS rebinding, and media URLs yt-dlp derives from remote
metadata — for any backend that resolves through Python's socket module.
Native resolvers (curl_cffi/libcurl via ``--impersonate``) bypass the socket
guard; network isolation (e.g. Docker) remains the backstop for those.
Known limitations — network isolation (e.g. Docker) remains the backstop for
all of these:
* The socket guard is installed only in the download subprocess. Metadata
extraction (``ytdl.DownloadQueue.__extract_info``) runs in the main process,
where installing a process-wide guard would reject the server's own bind on
``HOST=0.0.0.0``. So extraction — which also follows redirects — is covered
only by ``validate_url`` at ingress, not at connect time; a redirect from an
allowed host to an internal one during extraction is not blocked (a lower-
impact, blind SSRF, since the extraction response is not written to disk).
* Native resolvers (curl_cffi/libcurl via ``--impersonate``) resolve outside
Python's socket module and bypass the connect-time guard entirely.
"""
import ipaddress
+5
View File
@@ -1269,6 +1269,11 @@ class DownloadQueue:
return opts
def __extract_info(self, url, ytdl_options_presets=None, ytdl_options_overrides=None):
# NOTE: extraction runs in the main process, so the connect-time socket
# guard (installed only in the download subprocess) does not apply here.
# The ingress validate_url check guards the submitted URL, but redirects
# followed during extraction are not re-validated. See url_guard's module
# docstring for why the guard can't be installed process-wide.
debug_logging = logging.getLogger().isEnabledFor(logging.DEBUG)
user_opts = self._build_ytdl_options(ytdl_options_presets, ytdl_options_overrides)
params = {