VYPR
High severityNVD Advisory· Published Mar 24, 2026· Updated Mar 26, 2026

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

CVE-2026-33509

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.

PackageAffected versionsPatched versions
pyload-ngPyPI
>= 0.4.0, <= 0.5.0b3.dev96

Affected products

1

Patches

1
f5e284fcdfea

fix GHSA-r7mc-x6x7-cqxx security advisory

https://github.com/pyload/pyloadGammaC0deMar 20, 2026via ghsa
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

News mentions

0

No linked articles in our index yet.