high · 8.8CVE-2026-59177Sep 10, 2026

CVE-2026-59177: esphome-device-builder Unauthenticated Dashboard Access via Unrestricted Ingress Bind

Shubham Kandhare
Security Engagement Manager, SecureLayer7

The ESPHome Device Builder Home Assistant add-on exposed its password-free dashboard to every device on the local network because the internal ingress site accidentally listened on all network…

Packageesphome-device-builder
Ecosystempip
Affected< 1.0.10
Fixed in1.0.10
CVE-2026-59177: esphome-device-builder Unauthenticated Dashboard Access via Unrestricted Ingress Bind

The problem

The HA add-on's ingress site is intentionally unauthenticated. The supervisor's proxy is supposed to authenticate the browser before the request ever reaches the site. That model only holds if the ingress site is bound to addresses the LAN cannot reach.

Before 1.0.10, the site bound 0.0.0.0. The add-on runs in host-network mode for mDNS, so 0.0.0.0 included the host's physical LAN interface. Any device on the same network, no credentials required, could connect directly to http://<ha-ip>:<ingress_port>/ and skip the supervisor entirely.

The impact is severe. ESPHome's own threat model documents that an authenticated dashboard caller has host-equivalent capability: arbitrary Python at compile time via external_components:, arbitrary shell through compile and validation subprocesses, and read/write access to the HA config directory the add-on mounts.

Proof of concept

A working proof-of-concept for CVE-2026-59177 in esphome-device-builder, with the exact payload below.

bash
# From any device on the same LAN as the Home Assistant host:
# <ha-ip>  = your Home Assistant IP, e.g. 192.168.1.10
# <ingress_port> = the supervisor-allocated ingress port (visible in add-on logs)

curl -v http://<ha-ip>:<ingress_port>/

# Returns the full dashboard HTML with no authentication challenge.
# From there, the REST/WebSocket API is equally open, e.g.:
curl http://<ha-ip>:<ingress_port>/api/devices

# No token, no cookie, no credentials of any kind needed.

The root cause is CWE-605 (Binding to an Unrestricted IP Address). The ingress server called bind('0.0.0.0', ingress_port). Because the container uses host networking, that wildcard resolved to every interface on the HA host, including its LAN NIC. The no-auth site was never meant to be reachable from the LAN; the only thing preventing it was the bind address, and that address was wrong.

The patch (PR #1565, commit b6387db) changed the default bind to two explicit addresses: 127.0.0.1 (for HA core's ESPHome integration, which connects locally) and 172.30.32.1 (the supervisor gateway, which the ingress proxy connects through). It also added ingress_peer_guard, a middleware layer that returns 403 to any TCP peer whose source address is not 127.0.0.1 or 172.30.32.2 (the supervisor's own address).

This mirrors the legacy add-on nginx allow 127.0.0.1; allow 172.30.32.2; deny all ACL, and means the bind address alone is no longer the only barrier.

The fix

Upgrade to esphome-device-builder 1.0.10 or newer. The fix is delivered by updating the ESPHome HA add-on to any version that bundles device-builder 1.0.10+. If upgrading immediately is not possible, add a host or router firewall rule that blocks external access to the add-on's ingress port, allowing only 127.0.0.1 and 172.30.32.0/24.

Accessing the dashboard through the normal Home Assistant sidebar URL remains safe regardless of version, as that path goes through the supervisor's authenticated ingress proxy.

Reporter not attributed.

References: [1][2][3][4]

Related research