CVE-2026-33509
pyload-ng: SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
pyLoad is a free and open-source download manager written in Python. From version 0.4.0 to before version 0.5.0b3.dev97, the set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction. This issue has been patched in version 0.5.0b3.dev97.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
7.5
pyload-ng: SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
pyLoad is a free and open-source download manager written in Python. From version 0.4.0 to before version 0.5.0b3.dev97, the set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction. This issue has been patched in version 0.5.0b3.dev97.
- Record
CVE-2026-33509- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-269
- Updated
- 2026-11-02
EUVDEUVD-2026-20072
7.5
pyLoad is a free and open-source download manager written in Python. From version 0.4.0 to before version 0.5.0b3.dev97, the set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction. This issue has been patched in version 0.5.0b3.dev97.
- Record
EUVD-2026-20072- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-r7mc-x6x7-cqxx
7.5
pyLoad SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
Summary
The set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction.
Details
The vulnerability chain spans two components:
1. Unrestricted config write — src/pyload/core/api/__init__.py:210-243
@permission(Perms.SETTINGS)
@post
def set_config_value(self, category: str, option: str, value: Any, section: str = "core") -> None:
self.pyload.addon_manager.dispatch_event(
"config_changed", category, option, value, section
)
if section == "core":
if category == "general" and option == "storage_folder":
# Forbid setting the download folder inside dangerous locations
# ... validation only for storage_folder ...
return
self.pyload.config.set(category, option, value) # No validation for any other option
The Perms.SETTINGS permission (value 128) is a non-admin permission flag. The only hardcoded validation is for general.storage_folder. The reconnect.script option is written directly to config with no path validation, allowlist, or sanitization.
2. Arbitrary script execution — src/pyload/core/managers/thread_manager.py:157-199
def try_reconnect(self):
if not (
self.pyload.config.get("reconnect", "enabled")
and self.pyload.api.is_time_reconnect()
):
return False
# ... checks if active downloads want reconnect ...
reconnect_script = self.pyload.config.get("reconnect", "script")
if not os.path.isfile(reconnect_script):
self.pyload.config.set("reconnect", "enabled", False)
self.pyload.log.warning(self._("Reconnect script not found!"))
return
# ... reconnect logic ...
try:
subprocess.run(reconnect_script) # Executes attacker-controlled path
except Exception:
# ...
The reconnect_script value comes directly from config. The only check is os.path.isfile() — the file must exist but there is no allowlist, no path restriction, and no signature verification.
3. Attacker also controls timing via same SETTINGS permission
The attacker can set reconnect.enabled=True, reconnect.start_time, and reconnect.end_time through the same set_config_value() endpoint to control when execution occurs. toggle_reconnect() at line 321 requires only Perms.STATUS — an even lower privilege.
4. Additional privilege escalation via config access
Beyond RCE, the same unrestricted config write allows SETTINGS users to:
- Read proxy credentials (
proxy.username/proxy.password) in plaintext viaget_config() - Redirect syslog to an attacker-controlled server (
log.syslog_host/log.syslog_port) - Disable SSL (
webui.use_ssl=False), rebind to0.0.0.0(webui.host) - Modify SSL certificate/key paths to enable MITM
PoC
Step 1: Set reconnect script to an attacker-controlled executable
Via API:
# Authenticate and get session (as user with SETTINGS permission)
curl -c cookies.txt -X POST 'http://target:8000/api/login' \
-d 'username=settingsuser&password=pass123'
# Set reconnect script to a known executable on the system
curl -b cookies.txt -X POST 'http://target:8000/api/set_config_value' \
-d 'category=reconnect&option=script&value=/tmp/exploit.sh§ion=core'
Via Web UI:
curl -b cookies.txt -X POST 'http://target:8000/json/save_config?category=core' \
-d 'reconnect|script=/tmp/exploit.sh&reconnect|enabled=True'
**Step 2:…
- Record
GHSA-r7mc-x6x7-cqxx- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-269
- Updated
- 2026-11-02
NVD
7.5
pyLoad is a free and open-source download manager written in Python. From version 0.4.0 to before version 0.5.0b3.dev97, the set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction. This issue has been patched in version 0.5.0b3.dev97.
- Record
CVE-2026-33509- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - CVSS 3.1
- 8.8 High
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-269
- Updated
- 2026-11-02
OSV
7.5
pyload-ng: SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
pyLoad is a free and open-source download manager written in Python. From version 0.4.0 to before version 0.5.0b3.dev97, the set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction. This issue has been patched in version 0.5.0b3.dev97.
- Record
CVE-2026-33509- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-269
- Updated
- 2026-11-02
OSVGHSA-r7mc-x6x7-cqxx
7.5
pyLoad SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
Summary
The set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction.
Details
The vulnerability chain spans two components:
1. Unrestricted config write — src/pyload/core/api/__init__.py:210-243
@permission(Perms.SETTINGS)
@post
def set_config_value(self, category: str, option: str, value: Any, section: str = "core") -> None:
self.pyload.addon_manager.dispatch_event(
"config_changed", category, option, value, section
)
if section == "core":
if category == "general" and option == "storage_folder":
# Forbid setting the download folder inside dangerous locations
# ... validation only for storage_folder ...
return
self.pyload.config.set(category, option, value) # No validation for any other option
The Perms.SETTINGS permission (value 128) is a non-admin permission flag. The only hardcoded validation is for general.storage_folder. The reconnect.script option is written directly to config with no path validation, allowlist, or sanitization.
2. Arbitrary script execution — src/pyload/core/managers/thread_manager.py:157-199
def try_reconnect(self):
if not (
self.pyload.config.get("reconnect", "enabled")
and self.pyload.api.is_time_reconnect()
):
return False
# ... checks if active downloads want reconnect ...
reconnect_script = self.pyload.config.get("reconnect", "script")
if not os.path.isfile(reconnect_script):
self.pyload.config.set("reconnect", "enabled", False)
self.pyload.log.warning(self._("Reconnect script not found!"))
return
# ... reconnect logic ...
try:
subprocess.run(reconnect_script) # Executes attacker-controlled path
except Exception:
# ...
The reconnect_script value comes directly from config. The only check is os.path.isfile() — the file must exist but there is no allowlist, no path restriction, and no signature verification.
3. Attacker also controls timing via same SETTINGS permission
The attacker can set reconnect.enabled=True, reconnect.start_time, and reconnect.end_time through the same set_config_value() endpoint to control when execution occurs. toggle_reconnect() at line 321 requires only Perms.STATUS — an even lower privilege.
4. Additional privilege escalation via config access
Beyond RCE, the same unrestricted config write allows SETTINGS users to:
- Read proxy credentials (
proxy.username/proxy.password) in plaintext viaget_config() - Redirect syslog to an attacker-controlled server (
log.syslog_host/log.syslog_port) - Disable SSL (
webui.use_ssl=False), rebind to0.0.0.0(webui.host) - Modify SSL certificate/key paths to enable MITM
PoC
Step 1: Set reconnect script to an attacker-controlled executable
Via API:
# Authenticate and get session (as user with SETTINGS permission)
curl -c cookies.txt -X POST 'http://target:8000/api/login' \
-d 'username=settingsuser&password=pass123'
# Set reconnect script to a known executable on the system
curl -b cookies.txt -X POST 'http://target:8000/api/set_config_value' \
-d 'category=reconnect&option=script&value=/tmp/exploit.sh§ion=core'
Via Web UI:
curl -b cookies.txt -X POST 'http://target:8000/json/save_config?category=core' \
-d 'reconnect|script=/tmp/exploit.sh&reconnect|enabled=True'
**Step 2:…
- Record
GHSA-r7mc-x6x7-cqxx- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Weakness
- CWE-269
- Updated
- 2026-11-02
OSVPYSEC-2026-2996
7.5
pyLoad SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
Summary
The set_config_value() API endpoint allows users with the non-admin SETTINGS permission to modify any configuration option without restriction. The reconnect.script config option controls a file path that is passed directly to subprocess.run() in the thread manager's reconnect logic. A SETTINGS user can set this to any executable file on the system, achieving Remote Code Execution. The only validation in set_config_value() is a hardcoded check for general.storage_folder — all other security-critical settings including reconnect.script are writable without any allowlist or path restriction.
Details
The vulnerability chain spans two components:
1. Unrestricted config write — src/pyload/core/api/__init__.py:210-243
@permission(Perms.SETTINGS)
@post
def set_config_value(self, category: str, option: str, value: Any, section: str = "core") -> None:
self.pyload.addon_manager.dispatch_event(
"config_changed", category, option, value, section
)
if section == "core":
if category == "general" and option == "storage_folder":
# Forbid setting the download folder inside dangerous locations
# ... validation only for storage_folder ...
return
self.pyload.config.set(category, option, value) # No validation for any other option
The Perms.SETTINGS permission (value 128) is a non-admin permission flag. The only hardcoded validation is for general.storage_folder. The reconnect.script option is written directly to config with no path validation, allowlist, or sanitization.
2. Arbitrary script execution — src/pyload/core/managers/thread_manager.py:157-199
def try_reconnect(self):
if not (
self.pyload.config.get("reconnect", "enabled")
and self.pyload.api.is_time_reconnect()
):
return False
# ... checks if active downloads want reconnect ...
reconnect_script = self.pyload.config.get("reconnect", "script")
if not os.path.isfile(reconnect_script):
self.pyload.config.set("reconnect", "enabled", False)
self.pyload.log.warning(self._("Reconnect script not found!"))
return
# ... reconnect logic ...
try:
subprocess.run(reconnect_script) # Executes attacker-controlled path
except Exception:
# ...
The reconnect_script value comes directly from config. The only check is os.path.isfile() — the file must exist but there is no allowlist, no path restriction, and no signature verification.
3. Attacker also controls timing via same SETTINGS permission
The attacker can set reconnect.enabled=True, reconnect.start_time, and reconnect.end_time through the same set_config_value() endpoint to control when execution occurs. toggle_reconnect() at line 321 requires only Perms.STATUS — an even lower privilege.
4. Additional privilege escalation via config access
Beyond RCE, the same unrestricted config write allows SETTINGS users to:
- Read proxy credentials (
proxy.username/proxy.password) in plaintext viaget_config() - Redirect syslog to an attacker-controlled server (
log.syslog_host/log.syslog_port) - Disable SSL (
webui.use_ssl=False), rebind to0.0.0.0(webui.host) - Modify SSL certificate/key paths to enable MITM
PoC
Step 1: Set reconnect script to an attacker-controlled executable
Via API:
# Authenticate and get session (as user with SETTINGS permission)
curl -c cookies.txt -X POST 'http://target:8000/api/login' \
-d 'username=settingsuser&password=pass123'
# Set reconnect script to a known executable on the system
curl -b cookies.txt -X POST 'http://target:8000/api/set_config_value' \
-d 'category=reconnect&option=script&value=/tmp/exploit.sh§ion=core'
Via Web UI:
curl -b cookies.txt -X POST 'http://target:8000/json/save_config?category=core' \
-d 'reconnect|script=/tmp/exploit.sh&reconnect|enabled=True'
**Step 2:…
- Record
PYSEC-2026-2996- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
pyload-ngPyPI |
0.4.0 to 0.5.0b3.dev96 | None known |
pyload-ngPyPI |
0.4.0 to 0.5.0b3.dev96, plus listed versions 0.5.0a5.dev5280.5.0a5.dev5320.5.0a5.dev5350.5.0a5.dev5360.5.0a5.dev537 Show 45 moreShow less0.5.0a5.dev5390.5.0a5.dev5400.5.0a5.dev5450.5.0a5.dev5620.5.0a5.dev5640.5.0a5.dev5650.5.0a6.dev5700.5.0a6.dev5780.5.0a6.dev5870.5.0a7.dev5960.5.0a8.dev6020.5.0a9.dev6150.5.0a9.dev6290.5.0a9.dev6320.5.0a9.dev6410.5.0a9.dev6430.5.0a9.dev6550.5.0a9.dev8060.5.0b1.dev10.5.0b1.dev20.5.0b1.dev30.5.0b1.dev40.5.0b1.dev50.5.0b2.dev100.5.0b2.dev110.5.0b2.dev120.5.0b2.dev90.5.0b3.dev130.5.0b3.dev140.5.0b3.dev170.5.0b3.dev180.5.0b3.dev190.5.0b3.dev200.5.0b3.dev210.5.0b3.dev220.5.0b3.dev240.5.0b3.dev260.5.0b3.dev270.5.0b3.dev280.5.0b3.dev290.5.0b3.dev300.5.0b3.dev310.5.0b3.dev320.5.0b3.dev330.5.0b3.dev34 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-33509 is a high vulnerability (CVSS 7.5) in Pyload, published March 20, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.55%, the 46th percentile. No source names a fixed version.
References
github.com/pyload/pyload/security/advisories/GHSA-r7mc-x6x7-cqxx
github.com/pyload/pyload/commit/f5e284fcdfeaf08436bb03e5fcf697aaac659d8b
nvd.nist.gov/vuln/detail/CVE-2026-33509
github.com/advisories/GHSA-r7mc-x6x7-cqxx
github.com/CVEProject/cvelistV5/tree/main/cves/2026/33xxx/CVE-2026-33509.json
github.com/pyload/pyload
pypi.org/project/pyload-ng
Left out here: 50 versions and the rest of 3 source descriptions. The JSON record has them.