Advisory Database
  • Advisories
  • Dependency Scanning
  1. pypi
  2. ›
  3. pyload-ng
  4. ›
  5. CVE-2026-48737

CVE-2026-48737: pyLoad: SSRF guard bypass via IPv6 6to4/NAT64 transition wrappers of internal IPs

July 9, 2026

is_global_address in src/pyload/core/utils/web/check.py is the central guard against SSRF-style outbound connections in pyload-ng. It tests whether a given IP is “globally routable” via Python’s ipaddress.ip_address(value).is_global, and callers treat not is_global as “deny”:

def is_global_address(value):
try:
return ipaddress.ip_address(value).is_global
except ValueError:
return False

def is_global_host(value):
ips = host_to_ip(value)
return ips and all((is_global_address(ip) for ip in ips))

Python’s ipaddress.IPv6Address.is_global classifies the NAT64 well-known prefix as globally routable on every supported Python version (3.9 through 3.14 confirmed), and on older Pythons (3.9-3.11) the 6to4 prefix as well:

addressis_global on Py 3.9-3.11is_global on Py 3.12+wrapped IPv4
2002:7f00:0001:: (6to4)TrueFalse127.0.0.1
2002:0a00:0001:: (6to4)TrueFalse10.0.0.1
2002:a9fe:a9fe:: (6to4)TrueFalse169.254.169.254 (IMDS)
64:ff9b::a9fe:a9fe (NAT64)TrueTrue169.254.169.254
64:ff9b::7f00:1 (NAT64)TrueTrue127.0.0.1

pyload-ng declares python_requires = >=3.9 (setup.cfg), so deployments on Python 3.9-3.11 see the 6to4 path too. The NAT64 path is universal. is_global returns True for these wrappers, so is_global_address returns True and the deny check passes. The pycurl PREREQFUNC at src/pyload/core/network/http/http_request.py:680 consults the same helper just before TCP-connect:

if not self.allow_private_ip:
is_proxy_ip = self.http_proxy_host and self.http_proxy_host == (conn_primary_ip, conn_primary_port)
if not is_global_address(conn_primary_ip) and not is_proxy_ip:
return pycurl.PREREQFUNC_ABORT
return pycurl.PREREQFUNC_OK

On a host with 6to4 routing (legacy operator tunnels; 2002::/16 still configurable) or NAT64 (cloud IPv6-only subnets with NAT64 gateway), the encoded form routes to the embedded IPv4 and the curl connection terminates at the internal endpoint, defeating the deny.

is_global_host (the helper that callers like parse_urls use against a URL hostname) feeds through host_to_ip which pins family=AF_INET, so hostname-based reach to these forms relies on the attacker supplying an IPv6 literal in the URL — but the curl PREREQFUNC sees the actual resolved IP (the AAAA returned for the hostname), so a hostname with an AAAA record set to one of the bypass forms reaches the same gap.

Cross-reference: this is the same incomplete-coverage class as pydantic-ai’s GHSA-cqp8-fcvh-x7r3 / CVE-2026-46678. pyload-ng’s prior SSRF advisories GHSA-7gvf-3w72-p2pg and GHSA-8rp3-xc6w-5qp5 both went through is_global_host / is_global_address; the IPv6 transition gap is orthogonal to those redirect-bypass classes.

References

  • github.com/advisories/GHSA-m5x5-28jr-gpjj
  • github.com/pyload/pyload/security/advisories/GHSA-m5x5-28jr-gpjj
  • nvd.nist.gov/vuln/detail/CVE-2026-48737

Code Behaviors & Features

Detect and mitigate CVE-2026-48737 with GitLab Dependency Scanning

Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →

Affected versions

All versions up to 0.5.0-b.3.dev100

Solution

Unfortunately, there is no solution available yet.

Impact 4.9 MEDIUM

CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:L

Learn more about CVSS

Weakness

  • CWE-918: Server-Side Request Forgery (SSRF)

Source file

pypi/pyload-ng/CVE-2026-48737.yml

Spotted a mistake? Edit the file on GitLab.

  • Site Repo
  • About GitLab
  • Terms
  • Privacy Statement
  • Contact

Page generated Sun, 08 Nov 2026 00:15:46 +0000.