Overview

Froxlor, a popular server management software, has a critical vulnerability in its API authentication mechanism. The vulnerability allows an attacker to bypass Two-Factor Authentication (2FA) when an API key and secret are compromised. This means that even if a user has enabled 2FA on their account, an attacker can still access all API operations without providing a second factor.

Technical Details

The vulnerability is located in the `FroxlorRPC::validateAuth` method, which does not enforce 2FA when authenticating with an API key and secret. The web UI, on the other hand, correctly requires a TOTP code after password verification. The affected code is located in `lib/Froxlor/Api/FroxlorRPC.php:75-105`. ```php private static function validateAuth(string $key, string $secret): bool { // ... // Missing: ANY check for type_2fa, TOTP verification, or 2FA status return true; } ```

Impact Analysis

The impact of this vulnerability is severe. An attacker who obtains a leaked API key and secret for a 2FA-protected account has full access to all API operations without providing a second factor. This allows access to sensitive resources, including: - Customer data: PII (name, email, address) readable and modifiable - Domains: Full control over domains, subdomains, DNS records - Email accounts: Create, read, delete email accounts and forwarders - FTP accounts: Access home directory paths and credentials - MySQL databases: Full database management - SSL certificates: Read private keys, modify certificate bindings - 165 API functions: Including all write operations

Mitigation

To mitigate this vulnerability, the following steps can be taken: 1. Add 2FA verification to `FroxlorRPC::validateAuth()`. When the authenticated user has `type_2fa != 0`, require a TOTP code as an additional API parameter. ```php // lib/Froxlor/Api/FroxlorRPC.php, after line 100: // Check 2FA if enabled for this user if (!empty($result['adminid'])) { $user = Database::pexecute_first( Database::prepare("SELECT type_2fa, data_2fa FROM panel_admins WHERE adminid = :id"), ['id' => $result['adminid']] ); } else { $user = Database::pexecute_first( Database::prepare("SELECT type_2fa, data_2fa FROM panel_customers WHERE customerid = :id"), ['id' => $result['customerid']] ); } if ($user && $user['type_2fa'] != 0) { // Require X-2FA-Code header or 'totp_code' in request body $totp_code = $_SERVER['HTTP_X_2FA_CODE'] ?? null; if (empty($totp_code)) { throw new Exception('2FA code required', 401); } $tfa = new FroxlorTwoFactorAuth($user['data_2fa']); if (!$tfa->verifyCode($totp_code)) { throw new Exception('Invalid 2FA code', 403); } } ``` 2. Disable API key creation for accounts with 2FA enabled. 3. Require 2FA re-verification when generating new API keys.