Aug 19, 2026·8 min read·33 visits
An architectural flaw in Froxlor's standalone AJAX handler allows remote attackers to perform Cross-Site Request Forgery (CSRF) attacks to silently alter administrative API key parameters and gain persistent, unauthorized server access.
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.
Froxlor is an open-source server administration control panel designed to streamline the management of domain names, web hosting configurations, email setups, and system resources. Because of its administrative role, the panel possesses broad privileges over the underlying host system, making its security profile a critical element of the hosting infrastructure. Prior to the release of version 2.3.8, the system's architecture contained a design discrepancy that exposed sensitive administrative functions to unauthorized modification.
Specifically, the application's standalone AJAX handler, located at lib/ajax.php, operated independently of the main bootstrap sequence. While standard administrative actions routed through the global initialization file benefited from extensive validation controls, the asynchronous endpoint operated with minimal oversight. This isolation created a significant security gap, as it allowed state-changing requests to bypass centralized anti-CSRF protections completely.
The specific bug class identified is Cross-Site Request Forgery (CSRF), registered under CWE-352. The vulnerability allowed an unauthenticated attacker to manipulate active administrative sessions to perform critical modifications to the API key configuration. By exploiting this flaw, attackers could alter access controls and key validity periods, establishing persistent, out-of-band access to the control panel's management capabilities.
The root cause of CVE-2026-55593 resides in an architectural inconsistency between Froxlor's main request pipeline and its asynchronous callback handling system. Standard user interactions and API calls in Froxlor are routed through lib/init.php, which serves as a centralized controller. This initialization script is responsible for establishing sessions, verifying authentication states, and strictly enforcing cryptographic token checks on all incoming state-changing HTTP requests.
In contrast, the asynchronous communication architecture utilized a separate standalone script, lib/ajax.php, to minimize processing overhead and bypass full page rendering routines. However, this optimization bypassed lib/init.php entirely, thereby stripping the AJAX routing mechanism of the global security controls. Instead, lib/ajax.php initialized a standalone Ajax handler class, defined in lib/Froxlor/Ajax/Ajax.php, which lacked equivalent validation routines.
Before the implementation of the patch in version 2.3.8, the handle() function within the Ajax controller restricted its security checks to verifying whether a valid session cookie existed. It completely omitted checks for origin verification or cryptographic nonces. Once getValidatedSession() confirmed that a cookie was present and associated with an active user, the application proceeded to route and execute any requested sub-action, including administrative database modifications.
A detailed examination of the source code changes in commit 5f540fe361e7e13e8c5a32805b793a25e9e26a0e reveals the precise mechanisms used to introduce the fix. In the vulnerable version, the handle() method within lib/Froxlor/Ajax/Ajax.php did not contain any checks for CSRF tokens prior to processing state-changing actions. The patch remediates this by introducing an explicit token validation step for all state-changing HTTP request methods.
// lib/Froxlor/Ajax/Ajax.php - Patched Code Section
public function handle()
{
$this->userinfo = $this->getValidatedSession();
// Check if the incoming request is state-changing
if (in_array($_SERVER['REQUEST_METHOD'], ['POST', 'PUT', 'PATCH', 'DELETE'])) {
// Source token from POST payload or custom HTTP header
$current_token = Request::post('csrf_token', $_SERVER['HTTP_X_CSRF_TOKEN'] ?? null);
// Loose comparison check against the session token stored in the database
if ($current_token != CurrentUser::getField('csrf_token')) {
http_response_code(403);
return $this->errorResponse('CSRF validation failed');
}
}
// ... Routing logic continues ...
}To support this check, the session validation routine in getValidatedSession() was updated to ensure that every active user session has an associated cryptographic token. If no token is detected, a new 20-character identifier is generated and saved to the session. This token is then injected into the Twig templating system so that frontend scripts can access it.
// lib/Froxlor/Ajax/Ajax.php - getValidatedSession() Patch
private function getValidatedSession(): array
{
if (CurrentUser::hasSession() == false) {
throw new Exception("No valid session");
}
// Generate new CSRF token if one does not exist
if (!$csrf_token = CurrentUser::getField('csrf_token')) {
$csrf_token = Froxlor::genSessionId(20);
CurrentUser::setField('csrf_token', $csrf_token);
}
// Provide CSRF token globally to Twig templates
UI::initTwig();
$linker = new Linker('index.php');
UI::setLinker($linker);
UI::twig()->addGlobal('csrf_token', $csrf_token);
return CurrentUser::getData();
}Finally, the frontend JavaScript handler templates/Froxlor/assets/js/jquery/apikeys.js was modified to supply the CSRF token. The script intercepts outgoing asynchronous requests and inserts the token into the X-CSRF-TOKEN custom header, matching the backend's validation criteria.
// templates/Froxlor/assets/js/jquery/apikeys.js - Patched AJAX Call
$.ajax({
url: "lib/ajax.php?action=editapikey",
type: "POST",
dataType: "json",
beforeSend: function (request) {
// Retrieve CSRF token from DOM meta-tag and set custom header
request.setRequestHeader('X-CSRF-TOKEN', document.querySelector("meta[name='csrf-token']").getAttribute("content"));
},
data: {
id: akid,
allowed_from: _this.val(),
// ...
}
});Despite the efficacy of this patch, two notable technical observations persist. First, the use of a loose comparison operator (!=) in PHP instead of a strict type-safe check (!==) or a constant-time comparison library function (hash_equals) introduces hypothetical edge-case risks. Second, security teams must verify that all state-changing actions within the AJAX endpoint are strictly restricted to modifying HTTP verbs, as a GET request would completely bypass this validation block.
Exploitation of CVE-2026-55593 relies on a traditional Cross-Site Request Forgery vector targeting an authenticated administrator. Because the application did not validate origin or check for unique, session-linked tokens, an attacker could build a malicious payload designed to interact with the vulnerable endpoint on behalf of the victim. The attack requires the victim administrator to have an active session on the targeted Froxlor panel.
The attack scenario begins when the authenticated administrator is induced to visit a web page controlled by the attacker. This page contains an embedded script or hidden form designed to execute a cross-site POST request targeting the victim's Froxlor domain. When the request is dispatched to /lib/ajax.php?action=editapikey, the administrator's browser automatically appends the active session cookie associated with the target domain.
Because the endpoint only verifies the validity of the cookie, the request executes successfully in the context of the administrator's session. The payload is crafted to overwrite the allowed_from and valid_until parameters of a specific API key. By setting allowed_from to the attacker's IP or a wildcard value and removing the key's expiration date, the attacker gains permanent, direct programmatic access to the Froxlor API, completely bypassing the web interface.
The impact of this vulnerability is classified as High from an integrity perspective, resulting in a CVSS 3.1 base score of 6.5. Because the vulnerability allows an attacker to manipulate administrative API keys, the potential consequences extend far beyond a standard configuration bypass. API keys in Froxlor possess extensive permissions, allowing programmatic control over DNS zones, mail servers, user accounts, and system services.
Once an attacker successfully updates the whitelisted IP list (allowed_from) of an administrative API key to their own external address, they can interact directly with the Froxlor API. This interface allows them to create new administrative accounts, alter configuration files, and execute operations that can compromise the underlying Linux operating system. Additionally, removing expiration dates ensures that this access remains persistent even if the administrator logs out of the web interface.
Although the attack is write-only and does not directly leak data in the initial HTTP response, the resulting API access permits full read-and-write capabilities. Consequently, confidentiality and availability are ultimately compromised. The vulnerability bypasses the security boundaries of the server administration panel, transforming a single client-side interaction into a complete server-level compromise.
The primary and most effective remediation strategy is upgrading the Froxlor installation to version 2.3.8 or later. This release introduces the required token verification logic within lib/Froxlor/Ajax/Ajax.php and updates the frontend AJAX requests to send the necessary headers. Administrators should monitor package repositories and implement standard automated update procedures to ensure the patch is applied.
If an immediate software upgrade is not feasible, several defensive controls can be implemented to mitigate the risk. Setting the SameSite attribute of session cookies to Lax or Strict provides robust protection against cross-site request forgery attacks. This configuration forces modern browsers to omit session cookies when executing requests initiated by third-party origins, preventing the automated session propagation required for CSRF.
Additionally, administrators should implement strict network segmentations and monitoring policies. Restricting access to the Froxlor administrative panel to trusted internal networks or VPN tunnels significantly reduces the probability of a successful attack. Furthermore, security logs should be continuously reviewed for unexpected requests to /lib/ajax.php originating from unrecognized referrers or containing unauthorized state modifications.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Froxlor Froxlor | < 2.3.8 | 2.3.8 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-352 (Cross-Site Request Forgery) |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 6.5 Medium |
| EPSS Score | Not available |
| Impact | High Integrity Modification (I:H) |
| Exploit Status | Proof of Concept / Technical Analysis |
| CISA KEV Status | Not Listed |
The web application does not sufficiently verify whether a received HTTP request was intentionally submitted by the user who generated the request.
An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.
CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.
A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.
CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.
An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.
An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.