yt-dlp: Arbitrary Command Injection when using the `--netrc-cmd` option
Description
yt-dlp is a command-line audio/video downloader. Starting in version 2023.06.21 and prior to version 2026.02.21, when yt-dlp's --netrc-cmd command-line option (or netrc_cmd Python API parameter) is used, an attacker could achieve arbitrary command injection on the user's system with a maliciously crafted URL. yt-dlp maintainers assume the impact of this vulnerability to be high for anyone who uses --netrc-cmd in their command/configuration or netrc_cmd in their Python scripts. Even though the maliciously crafted URL itself will look very suspicious to many users, it would be trivial for a maliciously crafted webpage with an inconspicuous URL to covertly exploit this vulnerability via HTTP redirect. Users without --netrc-cmd in their arguments or netrc_cmd in their scripts are unaffected. No evidence has been found of this exploit being used in the wild. yt-dlp version 2026.02.21 fixes this issue by validating all netrc "machine" values and raising an error upon unexpected input. As a workaround, users who are unable to upgrade should avoid using the --netrc-cmd command-line option (or netrc_cmd Python API parameter), or they should at least not pass a placeholder ({}) in their --netrc-cmd argument.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A command injection vulnerability in yt-dlp's `--netrc-cmd` option allows arbitrary code execution via a maliciously crafted URL.
Vulnerability
Overview
CVE-2026-26331 is a command injection vulnerability in yt-dlp, a command-line audio/video downloader. The flaw. The issue affects versions starting from 2023.06.21 up to (but not including) 2026.02.21. The root cause lies in the --netrc-cmd command-line option (or netrc_cmd Python API parameter), which allows users to specify a shell command to retrieve login credentials. When a placeholder {} is used in the command, it is replaced with the netrc "machine" value. In certain extractors (GetCourseRuIE, TeachableIE, TeachableCourseIE), this machine value is dynamically sourced from the site's hostname, and wildcard matches are allowed for subdomains. An attacker can craft a URL with a malicious hostname that, when processed, injects arbitrary shell commands into the --netrc-cmd argument [1][2][4].
Exploitation and
Attack Surface
Exploitation requires the user to have the --netrc-cmd option enabled in their command line or configuration, or to use the netrc_cmd parameter in Python scripts. The attacker must deliver a maliciously crafted URL to the victim, which can be done via a crafted webpage that triggers an HTTP redirect to a URL with a specially crafted hostname. While the malicious URL itself may appear suspicious, an inconspicuous redirect can make the attack covert. No authentication is needed beyond the user's existing yt-dlp setup, and the attacker does not need any special network position [2][4].
Impact
Successful exploitation allows an attacker to execute arbitrary commands on the user's system with the privileges of the yt-dlp process. This could lead to full system compromise, data theft, or further lateral movement. The impact is considered high for users who employ the --netrc-cmd option [2][4].
Mitigation
The vulnerability is fixed in yt-dlp version 2026.02.21, which validates all netrc "machine" values and raises an error upon unexpected input, preventing injection [3][4]. Users who cannot upgrade should avoid using --netrc-cmd or, at minimum, not include the placeholder {} in their command argument. No evidence of exploitation in the wild has been found [2][4].
AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
yt-dlpPyPI | >= 2023.06.21, < 2026.02.21 | 2026.02.21 |
Affected products
2- Range: >=2023.06.21, <2026.02.21
- yt-dlp/yt-dlpv5Range: >= 2023.06.21, < 2026.02.21
Patches
11fbbe29b99dc[ie] Limit `netrc_machine` parameter to shell-safe characters
5 files changed · +17 −8
test/test_InfoExtractor.py+2 −0 modified@@ -76,6 +76,8 @@ def test_get_netrc_login_info(self): self.assertEqual(ie._get_netrc_login_info(netrc_machine='empty_pass'), ('user', '')) self.assertEqual(ie._get_netrc_login_info(netrc_machine='both_empty'), ('', '')) self.assertEqual(ie._get_netrc_login_info(netrc_machine='nonexistent'), (None, None)) + with self.assertRaises(ExtractorError): + ie._get_netrc_login_info(netrc_machine=';echo rce') def test_html_search_regex(self): html = '<p id="foo">Watch this <a href="http://www.youtube.com/watch?v=BaW_jenozKc">video</a></p>'
yt_dlp/extractor/common.py+10 −3 modified@@ -661,9 +661,11 @@ def initialize(self): if not self._ready: self._initialize_pre_login() if self.supports_login(): - username, password = self._get_login_info() - if username: - self._perform_login(username, password) + # try login only if it would actually do anything + if type(self)._perform_login is not InfoExtractor._perform_login: + username, password = self._get_login_info() + if username: + self._perform_login(username, password) elif self.get_param('username') and False not in (self.IE_DESC, self._NETRC_MACHINE): self.report_warning(f'Login with password is not supported for this website. {self._login_hint("cookies")}') self._real_initialize() @@ -1385,6 +1387,11 @@ def _html_search_regex(self, pattern, string, name, default=NO_DEFAULT, fatal=Tr def _get_netrc_login_info(self, netrc_machine=None): netrc_machine = netrc_machine or self._NETRC_MACHINE + if not netrc_machine: + raise ExtractorError(f'Missing netrc_machine and {type(self).__name__}._NETRC_MACHINE') + ALLOWED = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_' + if netrc_machine.startswith(('-', '_')) or not all(c in ALLOWED for c in netrc_machine): + raise ExtractorError(f'Invalid netrc machine: {netrc_machine!r}', expected=True) cmd = self.get_param('netrc_cmd') if cmd:
yt_dlp/extractor/getcourseru.py+1 −1 modified@@ -59,7 +59,7 @@ class GetCourseRuIE(InfoExtractor): 'marafon.mani-beauty.com', 'on.psbook.ru', ] - _BASE_URL_RE = rf'https?://(?:(?!player02\.)[^.]+\.getcourse\.(?:ru|io)|{"|".join(map(re.escape, _DOMAINS))})' + _BASE_URL_RE = rf'https?://(?:(?!player02\.)[a-zA-Z0-9-]+\.getcourse\.(?:ru|io)|{"|".join(map(re.escape, _DOMAINS))})' _VALID_URL = [ rf'{_BASE_URL_RE}/(?!pl/|teach/)(?P<id>[^?#]+)', rf'{_BASE_URL_RE}/(?:pl/)?teach/control/lesson/view\?(?:[^#]+&)?id=(?P<id>\d+)',
yt_dlp/extractor/pornhub.py+2 −2 modified@@ -128,7 +128,7 @@ class PornHubIE(PornHubBaseIE): _VALID_URL = rf'''(?x) https?:// (?: - (?:[^/]+\.)? + (?:[a-zA-Z0-9.-]+\.)? {PornHubBaseIE._PORNHUB_HOST_RE} /(?:(?:view_video\.php|video/show)\?viewkey=|embed/)| (?:www\.)?thumbzilla\.com/video/ @@ -534,7 +534,7 @@ def _extract_entries(self, webpage, host): class PornHubUserIE(PornHubPlaylistBaseIE): - _VALID_URL = rf'(?P<url>https?://(?:[^/]+\.)?{PornHubBaseIE._PORNHUB_HOST_RE}/(?:(?:user|channel)s|model|pornstar)/(?P<id>[^/?#&]+))(?:[?#&]|/(?!videos)|$)' + _VALID_URL = rf'(?P<url>https?://(?:[a-zA-Z0-9.-]+\.)?{PornHubBaseIE._PORNHUB_HOST_RE}/(?:(?:user|channel)s|model|pornstar)/(?P<id>[^/?#&]+))(?:[?#&]|/(?!videos)|$)' _TESTS = [{ 'url': 'https://www.pornhub.com/model/zoe_ph', 'playlist_mincount': 118,
yt_dlp/extractor/teachable.py+2 −2 modified@@ -102,7 +102,7 @@ class TeachableIE(TeachableBaseIE): _WORKING = False _VALID_URL = r'''(?x) (?: - {}https?://(?P<site_t>[^/]+)| + {}https?://(?P<site_t>[a-zA-Z0-9.-]+)| https?://(?:www\.)?(?P<site>{}) ) /courses/[^/]+/lectures/(?P<id>\d+) @@ -211,7 +211,7 @@ def _real_extract(self, url): class TeachableCourseIE(TeachableBaseIE): _VALID_URL = r'''(?x) (?: - {}https?://(?P<site_t>[^/]+)| + {}https?://(?P<site_t>[a-zA-Z0-9.-]+)| https?://(?:www\.)?(?P<site>{}) ) /(?:courses|p)/(?:enrolled/)?(?P<id>[^/?#&]+)
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-g3gw-q23r-pgqmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-26331ghsaADVISORY
- github.com/yt-dlp/yt-dlp/commit/1fbbe29b99dc61375bf6d786f824d9fcf6ea9c1aghsax_refsource_MISCWEB
- github.com/yt-dlp/yt-dlp/releases/tag/2026.02.21ghsax_refsource_MISCWEB
- github.com/yt-dlp/yt-dlp/security/advisories/GHSA-g3gw-q23r-pgqmghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.