# AdGuard Home: HTTP/2 Cleartext (h2c) Upgrade Authentication Bypass

AdGuard Home wraps auth middleware outside the h2c handler, so an h2c upgrade to a public path yields an unauthenticated HTTP/2 connection with full admin API access.

- Payout: Research
- Severity: critical
- Program: AdGuard Home
- Found by: mandreko
- Disclosed: 2026-03-12
- CVE: CVE-2026-32136
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-5fg6-wrq4-w5gh
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-5fg6-wrq4-w5gh
- Tags: area:web domain:web impact:ato impact:integrity impact:internal-access kind:research platform:ghsa sev:critical tech:go technique:source-review vuln:access-control vuln:auth-bypass

**Target:** AdGuard Home web admin API (internal/home/web.go)
**Root cause:** h2c.NewHandler captures the inner mux without auth middleware; the auth middleware wraps only the outer HTTP/1.1 handler. After an h2c upgrade the hijacked connection is served by http2.ServeConn using the unauthenticated inner mux.
**Steps:**
1. Open TCP connection to AdGuard Home (default port 3000).
2. Send `GET /control/login` with headers `Upgrade: h2c`, `Connection: Upgrade, HTTP2-Settings`, `HTTP2-Settings: AAMAAABkAAQAAP__` (public path passes isPublicResource).
3. Server responds `101 Switching Protocols`.
4. Complete HTTP/2 handshake (client preface + SETTINGS exchange).
5. Send HTTP/2 HEADERS frame for `GET /control/status` on stream 3.
6. Server returns HTTP 200 with full JSON status payload, no credentials supplied.
**How found:** Code reading of internal/home/web.go: noticed auth middleware wrapped the h2c handler at the outer layer while h2c.NewHandler stored the unauthenticated inner mux, meaning upgraded connections bypass auth.
**Exploitation:** Attacker performs h2c upgrade on a whitelisted public path, then issues arbitrary HTTP/2 requests over the hijacked connection to admin endpoints: read/modify DNS config, add filter lists, disable protection, change admin password, hijack DNS resolution for all clients.
**Escalation:** Full admin API access enables DNS hijacking of all network clients and admin password change for persistence.
**Insight:** When auth middleware wraps a protocol-upgrading handler (h2c, websocket, CONNECT), the upgraded connection is served by an inner handler captured at construction time; check whether that inner mux carries the auth middleware, and whether the upgrade path is whitelisted as public.

## Proof of concept (copied exactly from the original report)

**h2c upgrade request to /control/login**

```
Send HTTP/1.1 GET /control/login with headers:
       Upgrade: h2c
       Connection: Upgrade, HTTP2-Settings
       HTTP2-Settings: AAMAAABkAAQAAP__
```

**PoC script invocation with hijack-dns**

```
python3 poc_h2c_auth_bypass.py 192.168.1.15 80 --hijack-dns 8.8.8.8
    ====================================================================
    AdGuardHome -- h2c Authentication Bypass PoC
    CWE-287: Full API access without credentials
    ====================================================================
    Target  : [http://192.168.1.15:80](http://192.168.1.15/)
    Upgrade : /control/login  (whitelisted public path)
```

