Skip to content

Update dependency yt-dlp to v2026 [SECURITY]#91

Open
renovate[bot] wants to merge 1 commit intomasterfrom
renovate/pypi-yt-dlp-vulnerability
Open

Update dependency yt-dlp to v2026 [SECURITY]#91
renovate[bot] wants to merge 1 commit intomasterfrom
renovate/pypi-yt-dlp-vulnerability

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Aug 6, 2024

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
yt-dlp ^2024.0.0^2026.0.0 age confidence

GitHub Vulnerability Alerts

CVE-2024-38519

Summary

yt-dlp does not limit the extensions of downloaded files, which could lead to arbitrary filenames being created in the download folder (and path traversal on Windows). Since yt-dlp also reads config from the working directory (and on Windows executables will be executed from the yt-dlp directory) this could lead to arbitrary code being executed.

Patches

yt-dlp version 2024.07.01 fixes this issue by whitelisting the allowed extensions.
This means some very uncommon extensions might not get downloaded; however, it will also limit the possible exploitation surface.

Workarounds

It is recommended to upgrade yt-dlp to version 2024.07.01 as soon as possible, always have .%(ext)s at the end of the output template, and make sure you trust the websites that you are downloading from. Also, make sure to never download to a directory within PATH or other sensitive locations like your user directory, system32, or other binaries locations.

For users not able to upgrade:

  • Make sure the extension of the media to download is a common video/audio/sub/... one
  • Try to avoid the generic extractor (--ies default,-generic)
  • Keep the default output template (-o "%(title)s [%(id)s].%(ext)s)
  • Omit any of the subtitle options (--write-subs, --write-auto-subs, --all-subs, --write-srt)
  • Use --ignore-config --config-location ... to not load config from common locations

Details

One potential exploitation might look like this:

From a mimetype we do not know, we default to trimming the leading bit and using the remainder. Given a webpage that contains

<script type="application/ld+json">
{
    "@&#8203;context": "https://schema.org",
    "@&#8203;type": "VideoObject",
    "name": "ffmpeg",
    "encodingFormat": "video/exe",
    "contentUrl": "https://example.com/video.mp4"
}
</script>

this will try and download a file called ffmpeg.exe (-o "%(title)s.%(ext)s).
ffmpeg.exe will be searched for in the current directory, and so upon the next run arbitrary code can be executed.

Alternatively, when engineering a file called yt-dlp.conf to be created, the config file could contain --exec ... and so would also execute arbitrary code.

Acknowledgement

A big thanks to @​JarLob for independently finding a new application of the same underlying issue.
More can be read about on the dedicated GitHub Security Lab disclosure here: Path traversal saving subtitles (GHSL-2024-090)

References

GHSA-3v33-3wmw-3785

Impact

yt-dlp's DouyuTV and DouyuShow extractors used a cdn.bootcdn.net URL as a fallback for fetching a component of the crypto-js JavaScript library. When the Douyu extractor is used, yt-dlp extracts this JavaScript code and attempts to execute it externally using PhantomJS. bootcdn.net is owned by the bad actor responsible for the Polyfill JS supply chain attack that has been ongoing since at least June 2023. While there is no evidence that PhantomJS has been targeted by or is vulnerable to any attacks carried out by the Polyfill JS actor, there is the possibility that malicious JavaScript code may have been downloaded/cached by yt-dlp or executed by PhantomJS.

In order for this potential vulnerability to be exploited by any hypothetical attack, all 3 of the following conditions must be met:

  1. The user has PhantomJS installed on their system.
  2. The user passes a douyu.com or douyutv.com URL to yt-dlp as input, or passes a URL that redirects to one of these domains.
  3. cdnjs.cloudflare.com is unavailable or blocked at the time of extraction, necessitating the usage of the cdn.bootcdn.net fallback; or it had been unavailable during a previous run of the Douyu extractor and JavaScript code from cdn.bootcdn.net had been cached to disk.

Patches

yt-dlp version 2024.07.07 fixes this issue by removing the URL pointing to the malicious CDN and by invalidating any Douyu extractor cache data created by unpatched versions of yt-dlp.

Workarounds

It is recommended to upgrade yt-dlp to version 2024.07.07 as soon as possible.

For users not able to upgrade:

  • Avoid using the Douyu extractors (--ies default,-douyutv,-douyushow)
  • Uninstall (or do not install) PhantomJS

Acknowledgement

Thanks to @​LeSuisse for reporting this promptly after bootcdn.net was discovered to be under control of the same bad actor behind the polyfill.io supply chain attack.

References

CVE-2026-26331

Summary

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.

Impact

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.

Patches

yt-dlp version 2026.02.21 fixes this issue by validating all netrc "machine" values and raising an error upon unexpected input.

Workarounds

It is recommended to upgrade yt-dlp to version 2026.02.21 as soon as possible.

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.

Details

yt-dlp's --netrc-cmd option can be used to run any arbitrary shell command to retrieve site login credentials so that the user doesn't have to store the credentials as plaintext in the filesystem. The --netrc-cmd argument is a shell command with an optional placeholder ({}). If the placeholder is present in the argument, it is replaced with the netrc "machine" value, which specifies the site for which login credentials are needed.

The netrc "machine" value is usually explicitly defined in yt-dlp's extractor code for a given site. However, yt-dlp has four extractors where the netrc "machine" value needs to be dynamically sourced from the site's hostname. And in three of those extractors (GetCourseRuIE, TeachableIE and TeachableCourseIE), wildcard matches are allowed for one or more subdomains of the hostname. This can result in a netrc "machine" value that contains special shell characters.

The --netrc-cmd argument is executed by a modified version of Python's subprocess.Popen with shell=True, which means that any special characters may be interpreted by the host shell, potentially leading to arbitrary command injection.

Here is an example of maliciously crafted URL input that exploits the vulnerability:

> yt-dlp --netrc-cmd "echo {}" "https://;echo pwned>&2;#.getcourse.ru/video"
[GetCourseRu] Executing command: echo getcourseru
WARNING: [GetCourseRu] Failed to parse .netrc: bad toplevel token 'getcourseru' (-, line 2)
[GetCourseRu] Extracting URL: https://;echo pwned>&2;#.getcourse.ru/video
[GetCourseRu] Executing command: echo ;echo pwned>&2;
pwned
[GetCourseRu] No authenticators for ;echo pwned>&2;
[GetCourseRu] video: Downloading webpage

Although only 3 of yt-dlp's extractors are directly susceptible to this attack, yt-dlp's "generic" extractor will follow HTTP redirects and try to match the resulting URL with one of the dedicated extractors. This means that any URL processed by the generic extractor could ultimately lead to a maliciously crafted URL that is matched by one of the vulnerable extractors. Hypothetically, an attacker could create a website with an inconspicuous URL and legitimate-looking media content that would serve an HTTP redirect to a maliciously crafted URL when it detects a request from yt-dlp.

References


Release Notes

yt-dlp/yt-dlp (yt-dlp)

v2026.2.21

Compare Source

v2026.2.4

Compare Source

v2026.1.31

Compare Source

v2026.1.29

Compare Source

v2025.12.8

Compare Source

v2025.11.12

Compare Source

Important changes
  • An external JavaScript runtime is now required for full YouTube support
    yt-dlp now requires users to have an external JavaScript runtime (e.g. Deno) installed in order to solve the JavaScript challenges presented by YouTube. Read more
Core changes
Extractor changes
Downloader changes
Networking changes
Misc. changes

v2025.10.22

Compare Source

Important changes
  • A stopgap release with a TEMPORARY partial fix for YouTube support
    Some formats may still be unavailable, especially if cookies are passed to yt-dlp. The NEXT release, expected very soon, will require an external JS runtime (e.g. Deno) in order for YouTube downloads to work properly. Read more
  • The minimum required Python version has been raised to 3.10
    Python 3.9 has reached its end-of-life as of October 2025, and yt-dlp has now removed support for it. Read more
Core changes
Extractor changes
Misc. changes

v2025.10.14

Compare Source

Core changes
Extractor changes

v2025.9.26

Compare Source

v2025.9.23

Compare Source

v2025.9.5

Compare Source

v2025.8.27

Compare Source

v2025.8.22

Compare Source

v2025.8.20

Compare Source

v2025.8.11

Compare Source

v2025.7.21

Compare Source

v2025.6.30

Compare Source

v2025.6.25

Compare Source

v2025.6.9

Compare Source

v2025.5.22

Compare Source

v2025.4.30

Compare Source

v2025.3.31

Compare Source

v2025.3.27

Compare Source

v2025.3.26

Compare Source

v2025.3.25

Compare Source

v2025.3.21

Compare Source

v2025.2.19

Compare Source

v2025.1.26

Compare Source

v2025.1.15

Compare Source

v2025.1.12

Compare Source

v2024.12.23

Compare Source

Core changes
Extractor changes

v2024.12.13

Compare Source

Extractor changes
Misc. changes

v2024.12.6

Compare Source

v2024.12.3

Compare Source

v2024.11.18

Compare Source

Important changes
  • Login with OAuth is no longer supported for YouTube
    Due to a change made by the site, yt-dlp is no longer able to support OAuth login for YouTube. Read more
Core changes
Extractor changes
Misc. changes

v2024.11.4

Compare Source

v2024.10.22

Compare Source

Important changes
  • Following this release, yt-dlp's Python dependencies must be installed using the default group
    If you're installing yt-dlp with pip/pipx or requiring yt-dlp in your own Python project, you'll need to specify yt-dlp[default] if you want to also install yt-dlp's optional dependencies (which were previously included by default). Read more
  • py2exe is no longer supported
    This release's yt-dlp_min.exe will be the last, and it's actually a PyInstaller-bundled executable so that yt-dlp users updating their py2exe build with -U will be automatically migrated. Read more
Core changes
Extractor changes

Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@codecov
Copy link

codecov bot commented Aug 6, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.39%. Comparing base (c5e2d9a) to head (83a4b48).

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #91      +/-   ##
==========================================
+ Coverage   85.71%   88.39%   +2.67%     
==========================================
  Files           5        5              
  Lines         112      112              
==========================================
+ Hits           96       99       +3     
+ Misses         16       13       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@renovate renovate bot force-pushed the renovate/pypi-yt-dlp-vulnerability branch from 1e7df99 to 83a4b48 Compare October 28, 2024 16:02
@renovate renovate bot force-pushed the renovate/pypi-yt-dlp-vulnerability branch from 83a4b48 to 482b906 Compare February 24, 2026 15:45
@renovate renovate bot changed the title Update dependency yt-dlp to v2024.7.7 [SECURITY] Update dependency yt-dlp to v2026 [SECURITY] Feb 24, 2026
@renovate
Copy link
Contributor Author

renovate bot commented Feb 24, 2026

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: poetry.lock
Updating dependencies
Resolving dependencies...

Creating virtualenv videodownload-cdCmGeFV-py3.14 in /home/ubuntu/.cache/pypoetry/virtualenvs

The current project's supported Python range (>=3.8.3,<4.0.0) is not compatible with some of the required packages Python requirement:
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10
  - yt-dlp requires Python >=3.10, so it will not be satisfied for Python >=3.8.3,<3.10

Because no versions of yt-dlp match >=2026.0.0,<2026.1.1.233103.dev0 || >2026.1.1.233103.dev0,<2026.1.2.233036.dev0 || >2026.1.2.233036.dev0,<2026.1.3.233044.dev0 || >2026.1.3.233044.dev0,<2026.1.4.233103.dev0 || >2026.1.4.233103.dev0,<2026.1.5.233118.dev0 || >2026.1.5.233118.dev0,<2026.1.6.233142.dev0 || >2026.1.6.233142.dev0,<2026.1.16.233125.dev0 || >2026.1.16.233125.dev0,<2026.1.19.359.dev0 || >2026.1.19.359.dev0,<2026.1.19.233146.dev0 || >2026.1.19.233146.dev0,<2026.1.25.233128.dev0 || >2026.1.25.233128.dev0,<2026.1.27.233257.dev0 || >2026.1.27.233257.dev0,<2026.1.29 || >2026.1.29,<2026.1.29.165626.dev0 || >2026.1.29.165626.dev0,<2026.1.30.233459.dev0 || >2026.1.30.233459.dev0,<2026.1.31 || >2026.1.31,<2026.1.31.233334.dev0 || >2026.1.31.233334.dev0,<2026.2.3.233612.dev0 || >2026.2.3.233612.dev0,<2026.2.4 || >2026.2.4,<2026.2.4.233607.dev0 || >2026.2.4.233607.dev0,<2026.2.6.233518.dev0 || >2026.2.6.233518.dev0,<2026.2.7.233648.dev0 || >2026.2.7.233648.dev0,<2026.2.9.233747.dev0 || >2026.2.9.233747.dev0,<2026.2.12.233641.dev0 || >2026.2.12.233641.dev0,<2026.2.16.233630.dev0 || >2026.2.16.233630.dev0,<2026.2.17.233631.dev0 || >2026.2.17.233631.dev0,<2026.2.18.235726.dev0 || >2026.2.18.235726.dev0,<2026.2.19.233638.dev0 || >2026.2.19.233638.dev0,<2026.2.20.235452.dev0 || >2026.2.20.235452.dev0,<2026.2.21 || >2026.2.21,<2026.2.21.202150.dev0 || >2026.2.21.202150.dev0,<2026.2.22.233517.dev0 || >2026.2.22.233517.dev0,<2027.0.0
 and yt-dlp (2026.1.1.233103.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.2.233036.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.3.233044.dev0) requires Python >=3.10
 and yt-dlp (2026.1.4.233103.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.5.233118.dev0) requires Python >=3.10
 and yt-dlp (2026.1.6.233142.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.16.233125.dev0) requires Python >=3.10
 and yt-dlp (2026.1.19.359.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.19.233146.dev0) requires Python >=3.10
 and yt-dlp (2026.1.25.233128.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.27.233257.dev0) requires Python >=3.10
 and yt-dlp (2026.1.29.165626.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.30.233459.dev0) requires Python >=3.10
 and yt-dlp (2026.1.31.233334.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.3.233612.dev0) requires Python >=3.10
 and yt-dlp (2026.2.4.233607.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.6.233518.dev0) requires Python >=3.10
 and yt-dlp (2026.2.7.233648.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.9.233747.dev0) requires Python >=3.10
 and yt-dlp (2026.2.12.233641.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.16.233630.dev0) requires Python >=3.10
 and yt-dlp (2026.2.17.233631.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.18.235726.dev0) requires Python >=3.10
 and yt-dlp (2026.2.19.233638.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.20.235452.dev0) requires Python >=3.10
 and yt-dlp (2026.2.21.202150.dev0) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.2.22.233517.dev0) requires Python >=3.10
 and yt-dlp (2026.1.29) requires Python >=3.10, yt-dlp is forbidden.
And because yt-dlp (2026.1.31) requires Python >=3.10
 and yt-dlp (2026.2.4) requires Python >=3.10, yt-dlp is forbidden.
So, because yt-dlp (2026.2.21) requires Python >=3.10
 and videodownload depends on yt-dlp (^2026.0.0), version solving failed.

  • Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties
    
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"
    For yt-dlp, a possible solution would be to set the `python` property to ">=3.10,<4.0.0"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants