Every CVE Search/ Get API key

CVE-2026-41237

Froxlor has an incomplete fix for CVE-2026-30932

8.6 HighFix available

Froxlor is open source server administration software. In version 2.3.6 and earlier, the LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping. Version 2.3.7 contains an updated patch.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Exploit likelihood

0.27%Up 0.2 points since Jun 5, 2026
90%50%10%1%

What each source reports

CVE List Score used 8.6

Froxlor has an incomplete fix for CVE-2026-30932

Froxlor is open source server administration software. In version 2.3.6 and earlier, the LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping. Version 2.3.7 contains an updated patch.

Record
CVE-2026-41237
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
EUVDEUVD-2026-34316 8.6

Froxlor is open source server administration software. In version 2.3.6 and earlier, the LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping. Version 2.3.7 contains an updated patch.

Record
EUVD-2026-34316
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-j6fm-9rfm-j5hx 8.6

Froxlor has an incomplete fix for CVE-2026-30932

Summary

The LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping.

Affected Package

  • Ecosystem: Other
  • Package: froxlor
  • Affected versions: all versions before fix commit b34829262dc3
  • Patched versions: >= commit b34829262dc3

Severity

Medium -- CVSS

CWE

CWE-74 -- Improper Neutralization of Special Elements in Output Used by a Downstream Component (Injection)

Details

DNS record content is concatenated directly into bind9 zone files at DnsEntry.php line 83. Before the fix, LOC/RP/SSHFP/TLSA records had no content validation at all, enabling zone file injection via embedded newlines.

The fix adds format-specific regexes and field validation but has gaps: the LOC regex's \s+ matches newlines in PHP's PCRE engine, allowing a LOC record with a newline between fields to pass validation but produce multiple lines in the zone file. TLSA matchingType=0 only requires len(data) >= 2 with no upper bound, enabling arbitrarily large payloads. All validators return raw input without zone-file escaping.

PoC

#!/usr/bin/env python3
"""
CVE-2026-30932 - Incomplete DNS Record Content Validation in froxlor/froxlor

Affected component: lib/Froxlor/Api/Commands/DomainZones.php
Vulnerability type: Input Validation / DNS Zone File Injection
Patch: https://github.com/froxlor/froxlor/commit/b34829262dc32818b37f6a1eabb426d0b277a86b

The patch adds validation for LOC, RP, SSHFP, and TLSA DNS record types.
However, the sanitization is incomplete:

1. PRE-FIX: No validation at all - arbitrary content stored as DNS records.
2. POST-FIX BYPASS: LOC regex \s+ matches newlines; TLSA matchingType=0
   allows unbounded hex data; validators return raw input without escaping.
"""

import re
import sys
import string

def vulnerable_add_record(record_type, content):
    """Pre-fix: no validation for LOC, RP, SSHFP, TLSA."""
    errors = []
    if record_type in ('LOC', 'RP', 'SSHFP', 'TLSA') and content:
        pass
    return {"errors": errors, "content": content}


def validate_dns_loc(inp):
    """Replicates Validate::validateDnsLoc from the patch."""
    pattern = re.compile(
        r'^'
        r'(\d{1,2})\s+'
        r'(\d{1,2})\s+'
        r'(\d{1,2}(?:\.\d+)?)\s+'
        r'([NS])\s+'
        r'(\d{1,3})\s+'
        r'(\d{1,2})\s+'
        r'(\d{1,2}(?:\.\d+)?)\s+'
        r'([EW])\s+'
        r'(-?\d+(?:\.\d+)?)m'
        r'(?:\s+(\d+(?:\.\d+)?)m'
        r'(?:\s+(\d+(?:\.\d+)?)m'
        r'(?:\s+(\d+(?:\.\d+)?)m)?'
        r')?)?$',
        re.DOTALL
    )
    m = pattern.match(inp)
    if not m:
        return False

    lat_deg = int(m.group(1))
    lat_min = int(m.group(2))
    lat_sec = float(m.group(3))
    lon_deg = int(m.group(5))
    lon_min = int(m.group(6))
    lon_sec = float(m.group(7))

    if lat_deg > 90: return False
    if lat_min > 59: return False
    if lat_sec >= 60: return False
    if lon_deg > 180: return False
    if lon_min > 59: return False
    if lon_sec >= 60: return False

    return inp


def validate_dns_sshfp(inp):
    """Replicates Validate::validateDnsSshfp from the patch."""
    parts = inp.strip().split()
    if len(parts) != 3:
        return False

    algorithm, fp_type, fingerprint = parts

    valid_algorithms = [1, 2, 3, 4, 6]
    if not algorithm.isdigit() or int(algorithm) not in valid_algorithms:
        return False

    valid_types = [1, 2]
    if not fp_type.isdigit() or int(fp_type) not in valid_types:
        return False

    if not all(c in string.hexdigits for c in fingerprint):
        return False

    fp_type_int = int(fp_type)
    expected = {1: 40, 2: 64}.get(fp_type_int, 0)
    if len(fingerprint) != expected:
        return False

    return inp


def validate_dns_tlsa(inp):
    """Replicates Validate::validateDnsTlsa from the patch."""
    parts =…
Record
GHSA-j6fm-9rfm-j5hx
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
NVD 8.6

Froxlor is open source server administration software. In version 2.3.6 and earlier, the LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping. Version 2.3.7 contains an updated patch.

Record
CVE-2026-41237
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Weakness
CWE-74
Updated
2026-11-02
OSV 8.6

Froxlor has an incomplete fix for CVE-2026-30932

Froxlor is open source server administration software. In version 2.3.6 and earlier, the LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping. Version 2.3.7 contains an updated patch.

Record
CVE-2026-41237
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02
OSVGHSA-j6fm-9rfm-j5hx 8.6

Froxlor has an incomplete fix for CVE-2026-30932

Summary

The LOC record regex uses \s+ which matches newlines (allowing embedded newlines to pass), TLSA matchingType=0 has no upper bound on hex data length, and all validators return raw input without zone-file escaping.

Affected Package

  • Ecosystem: Other
  • Package: froxlor
  • Affected versions: all versions before fix commit b34829262dc3
  • Patched versions: >= commit b34829262dc3

Severity

Medium -- CVSS

CWE

CWE-74 -- Improper Neutralization of Special Elements in Output Used by a Downstream Component (Injection)

Details

DNS record content is concatenated directly into bind9 zone files at DnsEntry.php line 83. Before the fix, LOC/RP/SSHFP/TLSA records had no content validation at all, enabling zone file injection via embedded newlines.

The fix adds format-specific regexes and field validation but has gaps: the LOC regex's \s+ matches newlines in PHP's PCRE engine, allowing a LOC record with a newline between fields to pass validation but produce multiple lines in the zone file. TLSA matchingType=0 only requires len(data) >= 2 with no upper bound, enabling arbitrarily large payloads. All validators return raw input without zone-file escaping.

PoC

#!/usr/bin/env python3
"""
CVE-2026-30932 - Incomplete DNS Record Content Validation in froxlor/froxlor

Affected component: lib/Froxlor/Api/Commands/DomainZones.php
Vulnerability type: Input Validation / DNS Zone File Injection
Patch: https://github.com/froxlor/froxlor/commit/b34829262dc32818b37f6a1eabb426d0b277a86b

The patch adds validation for LOC, RP, SSHFP, and TLSA DNS record types.
However, the sanitization is incomplete:

1. PRE-FIX: No validation at all - arbitrary content stored as DNS records.
2. POST-FIX BYPASS: LOC regex \s+ matches newlines; TLSA matchingType=0
   allows unbounded hex data; validators return raw input without escaping.
"""

import re
import sys
import string

def vulnerable_add_record(record_type, content):
    """Pre-fix: no validation for LOC, RP, SSHFP, TLSA."""
    errors = []
    if record_type in ('LOC', 'RP', 'SSHFP', 'TLSA') and content:
        pass
    return {"errors": errors, "content": content}


def validate_dns_loc(inp):
    """Replicates Validate::validateDnsLoc from the patch."""
    pattern = re.compile(
        r'^'
        r'(\d{1,2})\s+'
        r'(\d{1,2})\s+'
        r'(\d{1,2}(?:\.\d+)?)\s+'
        r'([NS])\s+'
        r'(\d{1,3})\s+'
        r'(\d{1,2})\s+'
        r'(\d{1,2}(?:\.\d+)?)\s+'
        r'([EW])\s+'
        r'(-?\d+(?:\.\d+)?)m'
        r'(?:\s+(\d+(?:\.\d+)?)m'
        r'(?:\s+(\d+(?:\.\d+)?)m'
        r'(?:\s+(\d+(?:\.\d+)?)m)?'
        r')?)?$',
        re.DOTALL
    )
    m = pattern.match(inp)
    if not m:
        return False

    lat_deg = int(m.group(1))
    lat_min = int(m.group(2))
    lat_sec = float(m.group(3))
    lon_deg = int(m.group(5))
    lon_min = int(m.group(6))
    lon_sec = float(m.group(7))

    if lat_deg > 90: return False
    if lat_min > 59: return False
    if lat_sec >= 60: return False
    if lon_deg > 180: return False
    if lon_min > 59: return False
    if lon_sec >= 60: return False

    return inp


def validate_dns_sshfp(inp):
    """Replicates Validate::validateDnsSshfp from the patch."""
    parts = inp.strip().split()
    if len(parts) != 3:
        return False

    algorithm, fp_type, fingerprint = parts

    valid_algorithms = [1, 2, 3, 4, 6]
    if not algorithm.isdigit() or int(algorithm) not in valid_algorithms:
        return False

    valid_types = [1, 2]
    if not fp_type.isdigit() or int(fp_type) not in valid_types:
        return False

    if not all(c in string.hexdigits for c in fingerprint):
        return False

    fp_type_int = int(fp_type)
    expected = {1: 40, 2: 64}.get(fp_type_int, 0)
    if len(fingerprint) != expected:
        return False

    return inp


def validate_dns_tlsa(inp):
    """Replicates Validate::validateDnsTlsa from the patch."""
    parts =…
Record
GHSA-j6fm-9rfm-j5hx
CVSS 4.0
8.6 HighCVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-74
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
froxlor/froxlor
Packagist
through 2.3.6
2.3.7
froxlor/froxlor
Packagist
before 2.3.7, plus listed versions
0.10.00.10.0-rc10.10.0-rc20.10.10.10.10
Show 45 moreShow less
0.10.110.10.120.10.130.10.140.10.150.10.160.10.170.10.180.10.190.10.20.10.200.10.210.10.220.10.230.10.23.10.10.240.10.250.10.260.10.270.10.280.10.290.10.29.10.10.30.10.300.10.310.10.320.10.330.10.340.10.34.10.10.350.10.35.10.10.360.10.370.10.380.10.38.10.10.38.20.10.38.30.10.40.10.50.10.60.10.70.10.80.10.92.0.02.0.1
2.3.7

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-41237 is a high vulnerability (CVSS 8.6) in Froxlor, published May 29, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.27%, the 19th percentile. Fixed in froxlor/froxlor 2.3.7.

References

This page doesn't list everything

Left out here: 58 versions and the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open