pyload-ng: SETTINGS Permission Users Can Achieve Remote Code Execution via Unrestricted Reconnect Script Configuration
Description
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.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
pyload-ngPyPI | >= 0.4.0, <= 0.5.0b3.dev96 | — |
Affected products
1Patches
1f5e284fcdfeafix GHSA-r7mc-x6x7-cqxx security advisory
1 file changed · +31 −3
src/pyload/core/api/__init__.py+31 −3 modified@@ -216,9 +216,18 @@ def set_config_value(self, category: str, option: str, value: Any, section: str :param value: new config value :param section: 'plugin' or 'core """ - self.pyload.addon_manager.dispatch_event( - "config_changed", category, option, value, section - ) + + ADMIN_ONLY_OPTIONS = { + ("reconnect", "script"), + ("webui", "host"), + ("webui", "use_ssl"), + ("webui", "ssl_cert"), + ("webui", "ssl_key"), + ("log", "syslog_host"), + ("log", "syslog_port"), + ("proxy", "username"), + ("proxy", "password"), + } if section == "core": if category == "general" and option == "storage_folder": @@ -231,6 +240,21 @@ def set_config_value(self, category: str, option: str, value: Any, section: str if any(directories[0].startswith(d) for d in directories[1:]): return + # Require ADMIN role for security-critical settings + try: + try: + user_info = flask.g.user_info + except AttributeError: + user_info = flask.session + + if (category, option) in ADMIN_ONLY_OPTIONS and user_info.get("role") != Role.ADMIN: + self.pyload.log.error(self._("Writing config value {}/{} requires Admin role").format(category, option)) + return + + # Attempt to access outside an active Flask request + except RuntimeError: + pass + self.pyload.config.set(category, option, value) if category == "download" and option in ( @@ -242,6 +266,10 @@ def set_config_value(self, category: str, option: str, value: Any, section: str elif section == "plugin": self.pyload.config.set_plugin(category, option, value) + self.pyload.addon_manager.dispatch_event( + "config_changed", category, option, value, section + ) + @legacy("getConfig") @permission(Perms.SETTINGS) @get
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-r7mc-x6x7-cqxxghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-33509ghsaADVISORY
- github.com/pyload/pyload/commit/f5e284fcdfeaf08436bb03e5fcf697aaac659d8bghsaWEB
- github.com/pyload/pyload/security/advisories/GHSA-r7mc-x6x7-cqxxghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.