Aug 19, 2026·6 min read·1 visit
A high-severity second-order SQL injection in Froxlor allows authenticated administrative users to store malicious SQL payloads in admin profiles. When those profiles are queried by specific API actions, the unsanitized payload executes directly against the database, enabling complete database exfiltration. This issue is fully patched in Froxlor version 2.3.8.
An authenticated administrator with privileges to manage admin accounts (such as change_serversettings) can execute arbitrary SQL commands via a second-order SQL injection vulnerability. The flaw resides in Froxlor's administrative API endpoints, specifically during the handling of IP address mapping parameters which are stored as serialized arrays and later interpolated without sanitization into active database queries. This vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.
Froxlor is an open-source server administration control panel used to manage hosting environments. It exposes an API layer for administrative operations, including system configuration, database administration, and user management. This wide attack surface relies heavily on role-based access controls to isolate different tiers of administrative users.
This vulnerability, tracked as CVE-2026-54348 and GHSA-w27m-rmmf-g5w4, represents a classic trust-boundary violation. It falls under the class of second-order SQL injection (CWE-89). In this class, user input is initially stored safely in a database, only to be retrieved and executed insecurely in a different context or workflow later on.
The vulnerability allows high-privileged administrative attackers to compromise the database. By injecting a payload into administrative profile metadata, an attacker can extract sensitive credentials, manipulate backend settings, or potentially disrupt database integrity. The vulnerability affects all versions of Froxlor prior to 2.3.8.
The root cause of this vulnerability lies in the lack of data-type validation and strict boundary separation when processing array parameters. Specifically, the API endpoints Admins.add and Admins.update accept an arbitrary array under the ipaddress parameter. The application attempts to serialize this array into a JSON string using json_encode() and write it to the panel_admins.ip column.
During this initial write operation, the application performs a weak check: is_array($ipaddress) && $ipaddress > 0. In PHP, checking if an array is greater than zero simply verifies that the array has one or more elements. It does not validate or sanitize the types of the elements contained within the array itself. Consequently, arbitrary string inputs (including SQL operators and keywords) are successfully stored in the database as a valid JSON array.
The injection payload becomes active during read operations performed by endpoints such as IpsAndPorts.listing and domain validation logic. The application retrieves the JSON string from the database, decodes it back into a PHP array using json_decode(), and directly concatenates the raw array values into an SQL query's IN clause using the PHP implode() function. Because the values are directly concatenated rather than bound as parameterized variables or cast to integers, the interpreter treats the injected strings as structured SQL commands.
To analyze the vulnerable implementation, consider how the ipaddress parameter was processed in lib/Froxlor/Api/Commands/Admins.php prior to the patch. The array was encoded directly without ensuring its keys or values were restricted to numeric identifiers:
// Vulnerable code in lib/Froxlor/Api/Commands/Admins.php
'ip' => empty($ipaddress) ? '' : (is_array($ipaddress) && $ipaddress > 0 ? json_encode($ipaddress) : -1)When reading this data, lib/Froxlor/Api/Commands/IpsAndPorts.php executed the following unsafe dynamic SQL construction:
// Vulnerable query interpolation in lib/Froxlor/Api/Commands/IpsAndPorts.php
if (!empty($this->getUserDetail('ip')) && $this->getUserDetail('ip') != -1) {
$ip_where = 'WHERE id IN (' . implode(', ', json_decode($this->getUserDetail('ip'), true)) . ')';
$append_where = true;
}The patch in commit a1eaca5a1601c8a30e00814a4fc73ad0c185f89e addresses this on both the write and read paths. On the write path, the application now enforces that elements must be numeric using array_filter() and explicitly casts elements to integers with array_map('intval') before serialization:
// Patched code in lib/Froxlor/Api/Commands/Admins.php
if (is_array($ipaddress)) {
$ipaddress = array_filter($ipaddress, 'is_numeric');
}
// ...
'ip' => empty($ipaddress) ? '' : (is_array($ipaddress) && count($ipaddress) > 0 ? json_encode(array_map('intval', $ipaddress)) : -1)On the read path, even if legacy unvalidated strings exist in the database, the patch forces integer casting on the array elements before they are concatenated into the SQL statement, neutralizing any dynamic string elements:
// Patched query interpolation in lib/Froxlor/Api/Commands/IpsAndPorts.php
if (!empty($this->getUserDetail('ip')) && $this->getUserDetail('ip') != -1) {
$ip_ids = array_map('intval', json_decode($this->getUserDetail('ip'), true));
$ip_where = 'WHERE id IN (' . implode(', ', $ip_ids) . ')';
$append_where = true;
}Exploiting this second-order vulnerability requires a two-step administrative sequence. First, the attacker must have an administrative account with the change_serversettings privilege. The attacker targets the API endpoint Admins.add or Admins.update and supplies a maliciously crafted payload within the ipaddress array parameter.
Instead of passing standard numeric IDs, the attacker sends an array containing a nested SQL syntax breakout. For example, passing the array ["1", "1) UNION SELECT 1,2,3,4,group_concat(loginname, 0x3a, password),6,7,8,9,10 FROM panel_admins -- "] causes the JSON encoder to write the serialized string representation of this structure to the database column panel_admins.ip of the targeted user profile.
In the second stage, the attacker authenticates as the modified user or forces the execution of the listing query by invoking the IpsAndPorts.listing command. When the system executes this API action, it pulls the string from the database, decodes the array, and implodes it into the query. The database engine executes the command, processing the UNION SELECT payload, which allows the attacker to dump password hashes or bypass access controls.
The impact of this vulnerability is significant, as it grants complete access to the underlying database structure. An administrative attacker with restricted scope can elevate privileges, bypass regional controls, and extract sensitive information from all tables in the database.
The most critical threat vector is the exposure of administrative user credentials. By executing UNION statements, the attacker can extract user login names and their bcrypt-hashed passwords. Since many administrators reuse passwords across internal systems, this credential theft could lead to further compromise of the hosting infrastructure.
Furthermore, the ability to write to the database or alter system settings via SQL execution compromises the entire hosting panel environment. An attacker could register unauthorized domain records, create administrative backdoors, or tamper with customer configuration files, presenting a high threat to confidentiality, integrity, and availability.
The primary remediation for this vulnerability is upgrading Froxlor to version 2.3.8 or higher. The update implements a robust defense-in-depth security model by enforcing structural validations on both the write (input) and read (output) paths.
If patching immediately is not feasible, administrators should audit administrative accounts to ensure that only trusted personnel have the change_serversettings permission. Since the initial injection requires write access to the administrative configuration parameters, limiting this permission minimizes the available attack surface.
Additionally, administrators can execute database-level sanity checks to identify legacy malicious payloads already stored in the database. A query scanning the panel_admins.ip column for non-numeric arrays can pinpoint potential indicator files or compromised configurations before they are triggered by the application logic.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Froxlor Froxlor | < 2.3.8 | 2.3.8 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-89 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 | 7.2 (High) |
| EPSS Score | N/A |
| Impact | High (Confidentiality, Integrity, Availability) |
| Exploit Status | Proof of Concept (PoC) documented |
| KEV Status | Not listed on CISA KEV |
The software constructs an SQL command using input from an upstream component, but fails to neutralize elements that could modify the intended SQL command's logic.
A critical stored Cross-Site Scripting (XSS) vulnerability was identified in Froxlor server administration software panel before version 2.3.8. Authenticated customers with DNS editor privileges can inject malicious JavaScript into DNS TXT records. Because the application processes these values via a raw formatting callback without context-aware HTML entity encoding, the payload executes in the security context of administrative users who view the affected domain's DNS zones.
CVE-2026-54543 is a DNS Resource Record (RR) Injection vulnerability in Froxlor, an open-source server administration control panel. Prior to version 2.3.8, the DomainZones.add API command failed to perform strict sanitization and validation on the user-controlled record (label) and type parameters before serializing them into BIND-compatible zone files. An authenticated customer with DNS zone management permissions can inject control characters, breaking out of the original record context to define unauthorized resource records within managed zones.
CVE-2026-42533 is a critical security vulnerability discovered in NGINX Open Source, NGINX Plus, NGINX Ingress Controller, and related products, referred to as the 'Two-Pass Capture-Clobbering' bug. The flaw is situated within NGINX's internal evaluation engine when handling complex variables, exposing a heap-based buffer overflow and information leak when a configuration chains regular expression-based map directives with numbered capture groups. An unauthenticated remote attacker can exploit this weakness by transmitting crafted HTTP requests to trigger remote code execution or defeat ASLR.
Froxlor prior to version 2.3.8 contains a high-severity architectural flaw where the standalone lib/ajax.php entry point bypasses the centralized request validation in lib/init.php. Unauthenticated remote attackers can leverage Cross-Site Request Forgery (CSRF) to induce authenticated administrators to submit forged requests that modify API key whitelists and expiration dates, potentially yielding persistent, out-of-band administrative control.
An insecure data retrieval flaw in the Froxlor server administration panel API allows authenticated remote attackers to retrieve unredacted bcrypt password hashes and Base32-encoded Time-Based One-Time Password (TOTP) seeds. Affected endpoints include several 'get' and 'listing' handlers for customers, administrators, and FTP accounts. Utilizing these leaked parameters, attackers can crack the password hashes offline and concurrently generate valid second-factor authentication codes to completely bypass access controls.
CVE-2026-70666 is a critical Server-Side Request Forgery (SSRF) vulnerability in Netflix Lemur's ACME certificate management integration. Prior to version 1.9.3, the system allowed authority-role users to bypass initial ACME URL allowlist validations when updating an existing authority. Additionally, the underlying ACME network client blindly parsed and connected to dynamic endpoint URLs supplied in JSON responses from the configured ACME directory, allowing attackers to route arbitrary JWS-signed requests to internal services or cloud metadata endpoints.