diff --git a/README.md b/README.md index c4bd6ef0c7..77e88d6369 100644 --- a/README.md +++ b/README.md @@ -419,6 +419,8 @@ ## Network Options: --source-address IP Client-side IP address to bind to -4, --force-ipv4 Make all connections via IPv4 -6, --force-ipv6 Make all connections via IPv6 + --enable-file-urls Enable file:// URLs. This is disabled by + default for security reasons. ## Geo-restriction: --geo-verification-proxy URL Use this proxy to verify the IP address for diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index e7b4690590..7dc88e8a65 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -318,6 +318,7 @@ class YoutubeDL: If not provided and the key is encrypted, yt-dlp will ask interactively prefer_insecure: Use HTTP instead of HTTPS to retrieve information. (Only supported by some extractors) + enable_file_urls: Enable file:// URLs. This is disabled by default for security reasons. http_headers: A dictionary of custom headers to be used for all requests proxy: URL of the proxy server to use geo_verification_proxy: URL of the proxy to use for IP address verification @@ -3875,9 +3876,12 @@ def _setup_opener(self): # https://github.com/ytdl-org/youtube-dl/issues/8227) file_handler = urllib.request.FileHandler() - def file_open(*args, **kwargs): - raise urllib.error.URLError('file:// scheme is explicitly disabled in yt-dlp for security reasons') - file_handler.file_open = file_open + if not self.params.get('enable_file_urls'): + def file_open(*args, **kwargs): + raise urllib.error.URLError( + 'file:// URLs are explicitly disabled in yt-dlp for security reasons. ' + 'Use --enable-file-urls to enable at your own risk.') + file_handler.file_open = file_open opener = urllib.request.build_opener( proxy_handler, https_handler, cookie_processor, ydlh, redirect_handler, data_handler, file_handler) diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 9cb1324105..2e35db1bac 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -855,6 +855,7 @@ def parse_options(argv=None): 'legacyserverconnect': opts.legacy_server_connect, 'nocheckcertificate': opts.no_check_certificate, 'prefer_insecure': opts.prefer_insecure, + 'enable_file_urls': opts.enable_file_urls, 'http_headers': opts.headers, 'proxy': opts.proxy, 'socket_timeout': opts.socket_timeout, diff --git a/yt_dlp/options.py b/yt_dlp/options.py index 5bbb292dee..feb4b261d3 100644 --- a/yt_dlp/options.py +++ b/yt_dlp/options.py @@ -516,6 +516,11 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs): action='store_const', const='::', dest='source_address', help='Make all connections via IPv6', ) + network.add_option( + '--enable-file-urls', action='store_true', + dest='enable_file_urls', default=False, + help='Enable file:// URLs. This is disabled by default for security reasons.' + ) geo = optparse.OptionGroup(parser, 'Geo-restriction') geo.add_option(