GHSA-33mp-8p67-xj7c: Froxlor has Admin-to-Root Privilege Escalation via Input Validation Bypass + OS Command Injection
SummaryA typo in Froxlor's input validation code (`==` instead of `=`) completely disables email format checking for all settings fields declared as email type. This allows an authenticated admin to store arbitrary strings — including shell metacharacters — in the `panel.adminmail` setting. This value is later concatenated into a shell command executed as **root** by a cron job, where the pipe character `|` is explicitly whitelisted. The result is **full root-level Remote Code Execution**.Why This Is a Security Vulnerability (Not Just "Admin Using Admin Features")Froxlor is a **shared hosting control panel**. In production deployments:**Admin panel access does not equal root access.** Hosting providers assign the Froxlor admin role to staff who manage customer accounts, domains, and services through the web UI. These operators are not given SSH access or root shell on the underlying server. The boundary between "panel admin" and "OS root" is a deliberate security design.**Froxlor itself enforces this boundary.** The `safe_exec()` function (FileDir.php:224-264) exists specifically to prevent shell injection — it blocks `;`, `|`, `&`, `>`, `<`, `` ` ``, `$`, `~`, `?`. The email validation function (`validateFormFieldEmail`) exists specifically to ensure email fields contain valid emails. Both mechanisms are security boundaries that this vulnerability bypasses.**The root cause is an unintentional code defect.** The `==` operator on a standalone line is a no-op. No developer writes `$x == 'mail';` intentionally. This is a typo that silently breaks an entire class of input validation. It is not an admin feature.**Comparable CVEs exist for similar hosting panel escalations:**CVE-2022-44877 (CentOS Web Panel: admin→root RCE, CVSS 9.8)CVE-2023-27524 (Apache Superset: admin→RCE)CVE-2021-21315 (Node.js systeminformation: privileged user→RCE)CVE-2024-22024 (Ivanti: authenticated→system command execution)In each case, the fact that the attacker needs authenticated access did not prevent CVE assignment. The privilege escalation from "application admin" to "OS root" is the security impact.**Multi-tenant impact.** A single compromised or malicious admin gains root access to a server hosting potentially hundreds of customers. All customer data, databases, emails, and SSL keys are exposed.Vulnerability DetailsBug 1: Input Validation Bypass (CWE-482)**File:** `lib/Froxlor/Validate/Form/Data.php`**What happens:**`$fielddata['string_type']` is never set to `'mail'``validateFormFieldString()` checks `string_type` to decide which validation to applySince it's unset, `FILTER_VALIDATE_EMAIL` is never calledValidation falls through to a permissive fallback regex: `/^[^\r\n\t\f\0]*$/D`This regex allows `|`, `;`, `&`, `$`, `` ` ``, and all other shell metacharacters**Intended code:**Bug 2: OS Command Injection via acme.sh Installation (CWE-78)**File:** `lib/Froxlor/Cron/Http/LetsEncrypt/AcmeSh.php`**What happens:**`Settings::Get('panel.adminmail')` returns the unsanitized value from Bug 1`safe_exec()` normally blocks `|` as a dangerous characterBut `['|']` in the third argument whitelists pipe for this specific call (needed for `wget | sh`)An attacker's pipe-based payload passes through unblockedThe cron job runs as **root**The ChainProof of Conceptvuln 1 PoC:EnvironmentFroxlor 2.3.3, clean Docker install (Debian Bookworm, PHP 8.2, Apache 2.4)Default configuration, no modificationsStep 1: Confirm validation bypassvuln 2 PoC:**Output:**Step 2: Confirm value stored in databaseStep 3: Confirm root code executionSimulating AcmeSh.php line 428 inside the Docker container:**Result:**File created with **root:root** ownership. Arbitrary command execution as root is confirmed.Impact**Confidentiality:** Complete. Root access exposes all customer data, databases, SSL private keys, email contents.**Integrity:** Complete. Attacker can modify any file, inject backdoors, alter DNS records.**Availability:** Complete. Attacker can destroy the server, wipe databases, or deploy ransomware.**Scope:** Changed. The attack originates in the web application but impacts the underlying operating system.Suggested FixPrimary fix (Bug 1 — eliminates the root cause):Defense-in-depth (Bug 2 — even if validation is fixed):Defense-in-depth (ConfigServices.php):
CVSS v3.1: 9.1