
Unauthenticated authentication bypass in AdGuard Home
< 0.107.73via HTTP/2 cleartext (h2c) upgrade.
| CVE | CVE-2026-32136 |
| CVSS | 9.8 (Critical) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-287 (Improper Authentication) |
| Affected | AdGuard Home < 0.107.73 (PoC tested on v0.107.72) |
| Patched | v0.107.73 (commit c003e9f9c0) |
| Advisory | GHSA-5fg6-wrq4-w5gh |
The HTTP server in internal/home/web.go wraps the auth middleware outside h2c.NewHandler. When a client sends an HTTP/1.1 request with Upgrade: h2c to a public path (e.g. /login.html), the auth middleware lets it through and h2c.NewHandler hijacks the TCP connection to switch to HTTP/2. Every HTTP/2 stream that follows on the upgraded connection is dispatched directly to the inner mux — without ever passing through the auth middleware. Any /control/* admin endpoint can then be reached unauthenticated on the same socket.
The patch moves the auth middleware inside the handler given to h2c.NewHandler, so HTTP/2 frames after a cleartext upgrade hit the same auth check as HTTP/1.1 requests.
curl --http2-prior-knowledge does not trigger the bug — the server's HTTP/1.1 layer rejects the raw HTTP/2 preface with a 401./control/login returns 101 Switching Protocols too, but the 404 (POST-only endpoint) on stream 1 poisons subsequent streams. Use a static path that returns 200 OK (e.g. /login.html).# Kali / Debian / Ubuntu
sudo apt install -y python3-h2
python3 CVE-2026-32136.py <target-ip> [port] [path]
Defaults: port=80, path=/control/filtering/status.
$ python3 CVE-2026-32136.py 192.168.1.5 80 /control/filtering/status | jq .user_rules
[+] h2c upgrade successful — connection is now HTTP/2
[+] response status: 200
[
"||tracking.corp.example^",
"||analytics.internal.example^",
...
]
stdout is the raw response body; status messages are written to stderr so the output pipes cleanly into jq.
Upgrade to AdGuard Home 0.107.73 or later.
This proof-of-concept is published for educational and defensive research purposes. Do not run it against systems you do not own or have explicit authorization to test.
| Endpoint | Returns |
|---|
/control/filtering/status | filter list + user_rules |
/control/status | server status, listening interfaces |
/control/clients | DHCP / DNS client list |
/control/dns_info | upstream DNS servers |
/control/querylog | DNS query log (often contains internal hostnames) |