Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-62948

CVE-2026-62948: OpenWrt DHCPv6 XSS Vulnerability

CVE-2026-62948 is a cross-site scripting flaw in OpenWrt that allows attackers to inject malicious code through DHCPv6 hostnames. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-62948 Overview

CVE-2026-62948 is a stored cross-site scripting (XSS) vulnerability in OpenWrt, a Linux operating system for embedded devices. The odhcpd daemon writes DHCPv6 client FQDN option 39 hostnames into /tmp/odhcpd.leases without escaping. A malicious DHCPv6 client can inject newline characters to forge lease records. The LuCI web interface then renders these forged records as live HTML on the Active DHCPv6 Leases admin page through dom.append calls in luci.js, resulting in script execution in an authenticated administrator's browser. The issue is fixed in OpenWrt 25.12.5.

Critical Impact

A network-adjacent attacker sending a crafted DHCPv6 request can execute JavaScript in the router administrator's session, enabling full compromise of the OpenWrt device through authenticated LuCI actions.

Affected Products

  • OpenWrt versions prior to 25.12.5
  • odhcpd DHCPv6/RA/NDP daemon component
  • LuCI web interface (rpcd-mod-lucigetDHCPLeases, luci-mod-status DHCP views)

Discovery Timeline

  • 2026-07-15 - CVE-2026-62948 published to NVD
  • 2026-07-15 - Last updated in NVD database

Technical Details for CVE-2026-62948

Vulnerability Analysis

The vulnerability chains a data-injection flaw in odhcpd with an unsafe HTML rendering path in LuCI. The odhcpd daemon parses DHCPv6 FQDN option 39 and DHCPv4 option 12 hostnames supplied by clients. DNS labels can carry any octet under RFC 2181 section 11, so dn_expand() copies these bytes verbatim into the lease state file. Because statefiles_write_state6() and statefiles_write_state4() in src/statefiles.c write hostnames as space-delimited fields without escaping, a client-controlled newline terminates the current lease line and starts a forged one.

LuCI reads /tmp/odhcpd.leases through rpcd-mod-luci getDHCPLeases and returns the parsed rows to the browser. The status view scripts 40_dhcp.js and the shared luci.jsdom.append helper insert lease fields as raw HTML rather than escaped text. Any attribute-controlled markup in the hostname field executes when an administrator opens the Active DHCPv6 Leases page.

Root Cause

The defect is missing output encoding at two layers, classified as [CWE-79] Improper Neutralization of Input During Web Page Generation. odhcpd treats client-controlled hostnames as trusted structured data. LuCI subsequently treats file-sourced fields as trusted HTML fragments.

Attack Vector

Exploitation requires only network reachability to the OpenWrt DHCPv6 service and a subsequent visit by an authenticated LuCI administrator. The attacker sends a DHCPv6 SOLICIT or REQUEST message with a crafted FQDN option 39 payload containing an embedded newline and HTML script content.

c
/*
 * Escape a client-supplied hostname so it is safe to write as a single field
 * into the space-delimited, line-based state file: every byte that is not a
 * bare LDH character (the RFC 1035 section 2.3.1 "preferred name syntax" set
 * accepted by odhcpd_hostname_valid()) is encoded as \xNN. A DHCP client
 * controls its requested hostname (DHCPv4 option 12, DHCPv6 FQDN option) and,
 * since DNS labels may carry any octet (RFC 2181 section 11), dn_expand()/the
 * option parser copy the bytes verbatim - so without escaping a hostname could
 * embed a newline (forging an extra '#'-prefixed lease record) or a space
 * (forging additional fields). Valid hostnames are pure LDH and are copied
 * unchanged.
 */
static const char *statefiles_escape_hostname(char *dst, size_t dstlen, const char *src)
{
    size_t pos = 0;

    if (dstlen == 0)
        return dst;

    for (const unsigned char *c = (const unsigned char *)src; *c; c++) {
        if ((*c >= '0' && *c <= '9') ||
            (*c >= 'A' && *c <= 'Z') ||
            (*c >= 'a' && *c <= 'z') ||
            *c == '-' || *c == '_' || *c == '.') {
            if (pos + 1 >= dstlen)
                break;
            /* copy LDH bytes verbatim */
        }
    }
}

Source: OpenWrt ODHCPD Commit 68f3826

Detection Methods for CVE-2026-62948

Indicators of Compromise

  • Lease records in /tmp/odhcpd.leases containing non-LDH characters, HTML tags, or <script> fragments in the hostname field.
  • Multiple lease entries appearing from a single DHCPv6 transaction, indicating newline-based line forgery.
  • Unexpected outbound connections from the router shortly after an administrator visits the LuCI status page.

Detection Strategies

  • Parse /tmp/odhcpd.leases on OpenWrt devices and flag any hostname field containing characters outside the RFC 1035 LDH set (letters, digits, hyphen, underscore, dot).
  • Inspect DHCPv6 traffic for FQDN option 39 payloads containing 0x0A, 0x20, <, or > bytes within the domain label section.
  • Alert on LuCI administrator sessions that issue rpcd calls immediately after loading admin/status/leases.

Monitoring Recommendations

  • Forward DHCPv6 server logs and odhcpd state changes to a central logging platform for correlation with router configuration changes.
  • Monitor OpenWrt device configuration deltas (firewall rules, SSH keys, package installations) that follow a LuCI login event.
  • Track outbound HTTP requests from LuCI browser sessions to non-vendor domains as a signal of XSS payload callback.

How to Mitigate CVE-2026-62948

Immediate Actions Required

  • Upgrade all OpenWrt installations to version 25.12.5 or later, which includes the escaping fix in odhcpd and the %h formatter in LuCI DHCP views.
  • Restrict LuCI administrative access to trusted management networks and require authentication before any lease page is rendered.
  • Segment untrusted client networks so that unmanaged devices cannot reach the DHCPv6 service used for administrative infrastructure.

Patch Information

The fix is delivered in OpenWrt Release v25.12.5. The odhcpd change is tracked in ODHCPD Pull Request 404 and commit 68f3826, which introduces statefiles_escape_hostname(). The LuCI-side fix in commit 55379d0 applies the %h HTML-escape formatter to hostname and vendor columns. Full details are in the OpenWrt Security Advisory GHSA-hhmc-92hw-535f.

Workarounds

  • Disable the LuCI Active DHCPv6 Leases status page until patched packages are deployed if immediate upgrade is not feasible.
  • Block DHCPv6 traffic from untrusted VLANs to the router by adding firewall rules on UDP port 547.
  • Avoid opening LuCI in browsers used for other administrative tasks to reduce session risk from stored payloads.
bash
# Verify installed odhcpd and luci versions on OpenWrt
opkg list-installed | grep -E 'odhcpd|luci-mod-status|luci-base'

# Upgrade packages after syncing feeds
opkg update
opkg upgrade odhcpd odhcpd-ipv6only luci-mod-status luci-base

# Confirm the lease file no longer contains raw client-controlled bytes
awk '{ print $4 }' /tmp/odhcpd.leases | grep -vE '^[A-Za-z0-9._-]+$'

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.