CVE-2026-54348 Overview
Froxlor is open source server administration software used to manage hosting environments. A SQL injection vulnerability [CWE-89] exists in versions prior to 2.3.8. The Admins.add and Admins.update endpoints in lib/Froxlor/Api/Commands/Admins.php accept an attacker-controlled ipaddress array and store it as JSON in panel_admins.ip without enforcing numeric element types. When the poisoned account calls IpsAndPorts.listing, the array is decoded and concatenated into a SQL IN clause without casting or parameterization. The same unsafe pattern also exists in lib/Froxlor/Api/Commands/Domains.php. The issue is fixed in version 2.3.8.
Critical Impact
An authenticated administrator with change_serversettings permission can store a UNION-based SQL injection payload and retrieve arbitrary database content, including administrator login names and bcrypt password hashes, enabling privilege escalation.
Affected Products
- Froxlor server administration software versions prior to 2.3.8
- lib/Froxlor/Api/Commands/Admins.php (Admins.add and Admins.update endpoints)
- lib/Froxlor/Api/Commands/IpsAndPorts.php and lib/Froxlor/Api/Commands/Domains.php (sink locations)
Discovery Timeline
- 2026-08-18 - CVE-2026-54348 published to NVD
- 2026-08-19 - Last updated in NVD database
Technical Details for CVE-2026-54348
Vulnerability Analysis
The vulnerability is a stored SQL injection [CWE-89] that spans multiple Froxlor API command files. An authenticated administrator with change_serversettings permission submits an ipaddress array through Admins.add or Admins.update. Froxlor serializes the array as JSON and stores it in the panel_admins.ip column without validating that each element is numeric. When the poisoned account subsequently invokes IpsAndPorts.listing, the JSON is decoded and the array elements are concatenated directly into a SQL IN (...) clause. The identical unsafe concatenation pattern is also present in Domains.php, providing a second sink for the same stored payload.
Root Cause
The root cause is a failure to enforce type constraints on user-supplied data at both the storage layer and the query construction layer. The API accepts arbitrary strings inside the ipaddress array. The consumers of that stored value assume the elements are integer IDs and use implode(",", ...) to build a SQL clause without parameterization or casting.
Attack Vector
An authenticated administrator with change_serversettings permission stores a UNION-based SQL payload in the ipaddress field of a target admin account. The attacker then authenticates as the poisoned account and calls IpsAndPorts.listing or a domains endpoint to trigger execution. The resulting query returns arbitrary data from any table the database user can read, including credential material from panel_admins.
// Patch in lib/Froxlor/Api/Commands/Admins.php
// Enforces numeric-only elements before storing the ipaddress array
$password = Crypt::validatePassword($password, true);
// verify ip-address ids are numeric values only
if (is_array($ipaddress)) {
$ipaddress = array_filter($ipaddress, 'is_numeric');
}
$diskspace *= 1024;
$traffic *= 1024 * 1024;
// Patch in lib/Froxlor/Api/Commands/Domains.php
// Casts each decoded element to int before building the IN clause
if ($this->getUserDetail('ip') != "-1") {
$additional_ip_ids = array_map('intval', json_decode($this->getUserDetail('ip'), true));
$additional_ip_condition = " AND `ip` IN (" . implode(",", $additional_ip_ids) . ") ";
}
Source: GitHub Commit a1eaca5
Detection Methods for CVE-2026-54348
Indicators of Compromise
- Non-numeric values stored in the panel_admins.ip column, particularly strings containing SQL keywords such as UNION, SELECT, or --.
- Unexpected calls to Admins.add or Admins.update from accounts with change_serversettings permission followed by logins to a newly modified admin account.
- Database query logs showing malformed IN (...) clauses referencing columns from panel_admins or joined system tables.
Detection Strategies
- Audit the panel_admins table and confirm every element of the JSON-encoded ip field parses as an integer.
- Enable MySQL general query logging or slow query logging on the Froxlor database and search for queries containing IN ( alongside non-numeric tokens.
- Review Froxlor API access logs for Admins.update calls that modify the ipaddress field, correlated with subsequent IpsAndPorts.listing or Domains.listing calls.
Monitoring Recommendations
- Alert on any modification to admin accounts followed by authentication from that account within a short window.
- Monitor the web server access logs for API endpoints Admins.add, Admins.update, IpsAndPorts.listing, and Domains.listing and baseline normal request bodies.
- Track database error rates from the Froxlor service; UNION-based probing frequently produces column-count mismatch errors before a working payload is found.
How to Mitigate CVE-2026-54348
Immediate Actions Required
- Upgrade Froxlor to version 2.3.8 or later, which enforces is_numeric filtering on the ipaddress array and casts decoded IDs with intval.
- Rotate all administrator credentials after upgrade, since bcrypt hashes may have been exfiltrated from panel_admins.
- Review the panel_admins table and remove any non-numeric entries from stored ip values before restarting the service.
Patch Information
The fix is available in Froxlor 2.3.8. See the GitHub Release Notes for 2.3.8, the GitHub Security Advisory GHSA-w27m-rmmf-g5w4, and the remediation commit a1eaca5. The patch adds array_filter($ipaddress, 'is_numeric') in Admins.php and applies array_map('intval', ...) before building the IN clause in Domains.php and IpsAndPorts.php.
Workarounds
- Restrict the change_serversettings permission to a minimal set of trusted administrators until the patch is applied.
- Place the Froxlor admin interface behind an IP allowlist or VPN to limit the population able to reach the vulnerable endpoints.
- Deploy a web application firewall rule that rejects Admins.add and Admins.update requests whose ipaddress array elements are not integers.
# Upgrade Froxlor to the fixed release
git -C /var/www/froxlor fetch --tags
git -C /var/www/froxlor checkout 2.3.8
# Identify non-numeric entries stored in panel_admins.ip
mysql -e "SELECT adminid, loginname, ip FROM panel_admins WHERE ip REGEXP '[^0-9,\\[\\]\"]';" froxlor
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

