BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Security

[HIGH] Security Advisory: pyLoad: SSRF in parse_urls API endpoint via unvalidated URL parameter (pyload-ng)

pyLoad-ng, a Docker-friendly download manager for file hosters, exposes a server-side request forgery (SSRF) flaw in its API.

pyLoad-ng, a Docker-friendly download manager for file hosters, exposes a server-side request forgery (SSRF) flaw in its API. Authenticated users with “ADD” permission can force the server to fetch arbitrary URLs—including internal services, cloud metadata, and local files. This hits src/pyload/core/api/__init__.py at line 556, where get_url(url) via pycurl runs without validation, protocol checks, or IP blocks.

The vulnerability follows CWE-918. Attackers supply a URL parameter to /api/parse_urls, and pyLoad blindly pulls the content server-side to extract links. No sanitization means support for file://, gopher://, and dict:// protocols opens doors to local file reads, port scans, and internal network probes.

Attack Vectors and Proofs

Start with a standard setup: Docker image linuxserver/pyload-ng:latest on port 8084. Log in as any user with ADD perms, grab the CSRF token from the session.

Out-of-band exfiltration works via HTTP/DNS. Curl hits the endpoint with a Burp Collaborator URL like http://ssrf-proof./pyload-ssrf-poc. Expect 7 interactions: DNS lookups and HTTP requests confirm server-side fetches.

Local file reads shine through file://. Target file:///etc/passwd: empty response if exists. Try file:///nonexistent: pycurl error 37 (“Couldn’t open file”). This differential creates a file existence oracle. Confirmed reads include /etc/passwd, /etc/hosts, /proc/self/environ, pyLoad’s pyload.cfg, and SQLite DB at /config/data/pyload.db. While parse_urls only returns extracted URLs—not raw content—config files or env vars with URL-like strings leak indirectly.

curl -s -b "pyload_session_8000=..." -H "X-CSRFToken: ..." -H "Content-Type: application/x-www-form-urlencoded" \
  -d "url=file:///etc/passwd" \
  http://localhost:8084/api/parse_urls
# Response: {} (success, file read)

Port scanning internals: http://127.0.0.1:22/ yields connect error 7, confirming open/closed status. gopher://127.0.0.1:6379/_INFO hits Redis; dict://127.0.0.1:11211/stat probes Memcached.

Real-World Risks and Context

pyLoad-ng runs in homes, VPS, and shared hosting for automated downloads from Rapidgator, Mega, etc. Docker popularity (linuxserver.io image pulls millions) means many expose port 8000/8084 behind auth. But multi-user setups or weak creds amplify threats. A compromised account lets attackers map internals: cloud instances leak metadata at 169.254.169.254; self-hosts expose databases, configs, even pivot via gopher payloads.

Why this matters: SSRF ranks high (CVSS likely 7+). File oracles bypass “no raw read” limits—enumerate sensitive paths like SSH keys or API tokens. In Docker, host mounts (/config) dump user data. No auth bypass needed; just ADD perm, common for downloaders.

Skeptical note: pyLoad-ng devs maintain actively, but this slipped through pycurl’s broad protocol support. Similar bugs plague downloaders (e.g., past JDownloader flaws). Expose API publicly? Disaster. Even firewalled, insider or phished access risks leakage.

Mitigate now: Restrict ADD perms. Firewall API endpoints. Patch pending—watch GitHub (pyload/pyload-ng). Audit URL handlers in self-hosted tools. Run containers network-isolated. Test your setup: repro the PoCs. In security, blind fetches equal blind trust—don’t.

April 4, 2026 · 3 min · 12 views · Source: GitHub Security

Related