mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2026-06-12 13:54:28 +00:00
[cleanup] Misc (#16697)
Authored by: Grub4K, bashonly Co-authored-by: bashonly <bashonly@protonmail.com>
This commit is contained in:
parent
25056f0d2d
commit
821bef0f00
@ -342,5 +342,30 @@
|
|||||||
"action": "add",
|
"action": "add",
|
||||||
"when": "1fbbe29b99dc61375bf6d786f824d9fcf6ea9c1a",
|
"when": "1fbbe29b99dc61375bf6d786f824d9fcf6ea9c1a",
|
||||||
"short": "[priority] Security: [[CVE-2026-26331](https://nvd.nist.gov/vuln/detail/CVE-2026-26331)] [Arbitrary command injection with the `--netrc-cmd` option](https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-g3gw-q23r-pgqm)\n - The argument passed to the command in `--netrc-cmd` is now limited to a safe subset of characters"
|
"short": "[priority] Security: [[CVE-2026-26331](https://nvd.nist.gov/vuln/detail/CVE-2026-26331)] [Arbitrary command injection with the `--netrc-cmd` option](https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-g3gw-q23r-pgqm)\n - The argument passed to the command in `--netrc-cmd` is now limited to a safe subset of characters"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add",
|
||||||
|
"when": "98e42eb04486e00bf86479b24dbfe19321f652ee",
|
||||||
|
"short": "[priority] **The minimum supported versions of Deno, Node, and Bun have been raised.**\n The minimum required version of [Deno](https://github.com/yt-dlp/yt-dlp/issues/16767) is now `v2.3.0`; supported [Node](https://github.com/yt-dlp/yt-dlp/issues/16765) versions are `v22` and up; [Bun support has been deprecated](https://github.com/yt-dlp/yt-dlp/issues/16766) and limited to versions `1.2.11` through `1.3.14`."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add",
|
||||||
|
"when": "5faffa999fd33b373d47773e8ee639d072accec2",
|
||||||
|
"short": "[priority] Security: Usage of vulnerable conversions (e.g. `%()s`) with the `--exec` option is an all-too-common pitfall. To remedy this, `--exec` now only allows safe conversions in its command templates.\n - Most users can simply replace `%(...)s` with `%(...)q` in their `--exec` argument(s). Numeric conversions are unaffected by this change. Using unsafe conversions with `--exec` poses a significant security risk. [Read more](<https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-69qj-pvh9-c5wg>)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add",
|
||||||
|
"when": "e578e265f7c6ca94a74b30e0d8d6196a4d19fb6a",
|
||||||
|
"short": "[priority] Security: [[CVE-2026-50023](https://nvd.nist.gov/vuln/detail/CVE-2026-50023)] [Dangerous file type creation via insufficient filename sanitization](https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-c6mh-fpjc-4pr3)\n - Writing files with the extensions `.desktop`, `.url`, or `.webloc` is now only allowed in the context of `--write-link` functionality"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add",
|
||||||
|
"when": "2726572520238356bcf64aba2040228648b44c82",
|
||||||
|
"short": "[priority] Security: [[CVE-2026-50019](https://nvd.nist.gov/vuln/detail/CVE-2026-50019)] [File Downloader cookie leak with curl](https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-f7j3-774f-rfhj)\n - Impact is limited to users of `--downloader curl`; cookies are now properly passed to curl so that it respects their scope"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add",
|
||||||
|
"when": "25056f0d2d47adbd235a8d422fa62d68d0be2bc2",
|
||||||
|
"short": "[priority] Security: [[CVE-2026-50574](https://nvd.nist.gov/vuln/detail/CVE-2026-50574)] [Arbitrary code execution via manifest downloads with aria2c](https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-vx4q-3cr2-7cg2)\n - Impact is limited to users of `--downloader aria2c`\n - Support for downloading HLS and DASH formats with aria2c has been removed. Users affected by this change should migrate to use `-N` for concurrent fragment downloads via the native downloader"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -650,8 +650,8 @@ def update_requirements(
|
|||||||
modify_and_write_pyproject(pyproject_text, table_name=EXTRAS_TABLE, table=extras)
|
modify_and_write_pyproject(pyproject_text, table_name=EXTRAS_TABLE, table=extras)
|
||||||
|
|
||||||
# Generate/upgrade final lockfile that includes pinned extras
|
# Generate/upgrade final lockfile that includes pinned extras
|
||||||
print(f'Running: uv lock {upgrade_arg}', file=sys.stderr)
|
print('Running: uv lock', file=sys.stderr)
|
||||||
run_process('uv', 'lock', upgrade_arg, env=env)
|
run_process('uv', 'lock', env=env)
|
||||||
|
|
||||||
# Export bundle requirements; any updates to these are already recorded w/ uv.lock package diff
|
# Export bundle requirements; any updates to these are already recorded w/ uv.lock package diff
|
||||||
for target_suffix, target in BUNDLE_TARGETS.items():
|
for target_suffix, target in BUNDLE_TARGETS.items():
|
||||||
|
|||||||
@ -6,11 +6,11 @@ import sys
|
|||||||
import unittest
|
import unittest
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from yt_dlp.globals import all_plugins_loaded
|
|
||||||
|
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
|
|
||||||
|
from yt_dlp.globals import all_plugins_loaded
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
|||||||
@ -102,6 +102,7 @@ class HTTPTestHandler(http.server.BaseHTTPRequestHandler):
|
|||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(json.dumps(list(self.headers.items())).encode())
|
self.wfile.write(json.dumps(list(self.headers.items())).encode())
|
||||||
|
|
||||||
|
|
||||||
class HTTPTestServer(http.server.HTTPServer):
|
class HTTPTestServer(http.server.HTTPServer):
|
||||||
@property
|
@property
|
||||||
def address(self, /):
|
def address(self, /):
|
||||||
|
|||||||
@ -20,7 +20,12 @@ LAZY_EXTRACTORS = 'yt_dlp/extractor/lazy_extractors.py'
|
|||||||
class TestExecution(unittest.TestCase):
|
class TestExecution(unittest.TestCase):
|
||||||
def run_yt_dlp(self, exe=(sys.executable, 'yt_dlp/__main__.py'), opts=('--version', )):
|
def run_yt_dlp(self, exe=(sys.executable, 'yt_dlp/__main__.py'), opts=('--version', )):
|
||||||
stdout, stderr, returncode = Popen.run(
|
stdout, stderr, returncode = Popen.run(
|
||||||
[*exe, '--ignore-config', *opts], cwd=rootDir, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
[*exe, '--no-update', '--ignore-config', *opts],
|
||||||
|
cwd=rootDir,
|
||||||
|
text=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
print(stderr, file=sys.stderr)
|
print(stderr, file=sys.stderr)
|
||||||
self.assertEqual(returncode, 0)
|
self.assertEqual(returncode, 0)
|
||||||
return stdout.strip(), stderr.strip()
|
return stdout.strip(), stderr.strip()
|
||||||
|
|||||||
@ -1313,6 +1313,7 @@ class YoutubeDL:
|
|||||||
)$''')
|
)$''')
|
||||||
SAFE_EXEC_CONVERSIONS = 'difq'
|
SAFE_EXEC_CONVERSIONS = 'difq'
|
||||||
UNSAFE_DEFAULT_CHARS = '"\' \n\t;&|^$%*<>{}()[]`#\\'
|
UNSAFE_DEFAULT_CHARS = '"\' \n\t;&|^$%*<>{}()[]`#\\'
|
||||||
|
EXEC_ADVISORY_MSG = 'See https://github.com/yt-dlp/yt-dlp/security/advisories/GHSA-69qj-pvh9-c5wg for details'
|
||||||
|
|
||||||
def _from_user_input(field):
|
def _from_user_input(field):
|
||||||
if field == ':':
|
if field == ':':
|
||||||
@ -1440,12 +1441,21 @@ class YoutubeDL:
|
|||||||
# Validate safety of exec commands
|
# Validate safety of exec commands
|
||||||
if _exec:
|
if _exec:
|
||||||
if fmt[-1] not in SAFE_EXEC_CONVERSIONS:
|
if fmt[-1] not in SAFE_EXEC_CONVERSIONS:
|
||||||
raise UnsafeExecExpansionError(f'Unsafe conversion(s) in exec command: {outtmpl!r}')
|
raise UnsafeExecExpansionError(
|
||||||
|
f'Unsafe conversion(s) in exec command: {outtmpl!r}\n'
|
||||||
|
f'Conversions such as %()s are too dangerous to be used in '
|
||||||
|
f'--exec command templates; use %()q instead. {EXEC_ADVISORY_MSG}')
|
||||||
elif any(unsafe_char in default for unsafe_char in UNSAFE_DEFAULT_CHARS):
|
elif any(unsafe_char in default for unsafe_char in UNSAFE_DEFAULT_CHARS):
|
||||||
if default == na:
|
if default == na:
|
||||||
raise UnsafeExecExpansionError(f'Unsafe placeholder for exec command: {na!r}')
|
raise UnsafeExecExpansionError(
|
||||||
|
f'Unsafe placeholder for exec command: {na!r}\n'
|
||||||
|
f'The --output-na-placeholder argument also applies to '
|
||||||
|
f'--exec command templates. {EXEC_ADVISORY_MSG}')
|
||||||
else:
|
else:
|
||||||
raise UnsafeExecExpansionError(f'Unsafe default(s) in exec command: {outtmpl!r}')
|
raise UnsafeExecExpansionError(
|
||||||
|
f'Unsafe default(s) in exec command: {outtmpl!r}\n'
|
||||||
|
f'Conversions are not applied to --exec command template defaults, '
|
||||||
|
f'e.g. %(...|DEFAULT;)q. {EXEC_ADVISORY_MSG}')
|
||||||
|
|
||||||
flags = outer_mobj.group('conversion') or ''
|
flags = outer_mobj.group('conversion') or ''
|
||||||
str_fmt = f'{fmt[:-1]}s'
|
str_fmt = f'{fmt[:-1]}s'
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import time
|
|||||||
from .fragment import FragmentFD
|
from .fragment import FragmentFD
|
||||||
from ..postprocessor.ffmpeg import EXT_TO_OUT_FORMATS, FFmpegPostProcessor
|
from ..postprocessor.ffmpeg import EXT_TO_OUT_FORMATS, FFmpegPostProcessor
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
|
DownloadError,
|
||||||
Popen,
|
Popen,
|
||||||
RetryManager,
|
RetryManager,
|
||||||
_configuration_args,
|
_configuration_args,
|
||||||
@ -136,8 +137,6 @@ class ExternalFD(FragmentFD):
|
|||||||
self.to_screen(f'[download] Writing temporary cookies file to "{self._cookies_tempfile}"')
|
self.to_screen(f'[download] Writing temporary cookies file to "{self._cookies_tempfile}"')
|
||||||
# real_download resets _cookies_tempfile; if it's None then save() will write to cookiejar.filename
|
# real_download resets _cookies_tempfile; if it's None then save() will write to cookiejar.filename
|
||||||
self.ydl.cookiejar.save(self._cookies_tempfile, True, True)
|
self.ydl.cookiejar.save(self._cookies_tempfile, True, True)
|
||||||
with open(self.ydl.cookiejar.filename or self._cookies_tempfile, "r") as file:
|
|
||||||
print("cookies", repr(file.read()))
|
|
||||||
return self.ydl.cookiejar.filename or self._cookies_tempfile
|
return self.ydl.cookiejar.filename or self._cookies_tempfile
|
||||||
|
|
||||||
def _call_downloader(self, tmpfilename, info_dict):
|
def _call_downloader(self, tmpfilename, info_dict):
|
||||||
@ -224,8 +223,7 @@ class CurlFD(ExternalFD):
|
|||||||
else:
|
else:
|
||||||
cookies_file = self._write_cookies()
|
cookies_file = self._write_cookies()
|
||||||
if '=' in cookies_file:
|
if '=' in cookies_file:
|
||||||
# XXX: what to raise here?
|
raise DownloadError('curl version too old or temp directory contains `=`; please use another downloader or update curl')
|
||||||
raise RuntimeError('curl version too old or temp directory contains `=`; please use another downloader or update curl')
|
|
||||||
assert cookies_file != '-'
|
assert cookies_file != '-'
|
||||||
cmd += ['--cookie', cookies_file]
|
cmd += ['--cookie', cookies_file]
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user