# CoreDNS has TSIG authentication bypass on DoT, DoH, DoH3, DoQ, and gRPC

CoreDNS tsig plugin trusted transport TsigStatus() which returns nil on DoT/DoH/DoH3/DoQ/gRPC, letting clients without the shared secret bypass require all.

- Payout: Research
- Severity: high
- Program: CoreDNS
- Found by: manizada
- Disclosed: 2026-04-28
- CVE: CVE-2026-33190
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-qhmp-q7xh-99rh
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-qhmp-q7xh-99rh
- Tags: area:devices domain:network impact:internal-access kind:research platform:ghsa sev:high tech:go technique:chained technique:source-review vuln:access-control vuln:auth-bypass

**Target:** CoreDNS tsig plugin over DoT/DoH/DoH3/DoQ/gRPC transports
**Root cause:** The tsig plugin relies on w.TsigStatus() instead of verifying TSIG itself; DoH/DoH3/DoQ/gRPC writers hardcode TsigStatus() to nil and the DoT server builds a dns.Server without TsigSecret, so no verification ever occurs.
**Steps:**
1. Configure CoreDNS with tsig { require all } and serve DoT (tls://) and DoH (https://).
2. Send a query with no TSIG over plain TCP: get rcode=5 REFUSED (baseline).
3. Send a query with an invalid TSIG over plain TCP: get rcode=9 NOTAUTH (baseline).
4. Send the same invalid-TSIG query over DoT: get rcode=0 NOERROR with ancount=1.
5. Send the same invalid-TSIG query over DoH: get HTTP 200, rcode=0, ancount=1.
**How found:** Compared TSIG enforcement across transports: noticed plain DNS/TCP/UDP set TsigSecret on the dns.Server while the TLS server does not, and that DoH/DoQ/gRPC writer TsigStatus() implementations simply return nil, then built a differential PoC (TCP vs DoT vs DoH) to confirm.
**Exploitation:** An unauthenticated remote client without the TSIG shared secret sends queries over DoT/DoH/DoH3/DoQ/gRPC; the transport writer reports TsigStatus()==nil so the tsig plugin's require all check passes, granting access to zone data and privileged queries the deployment meant to restrict.
**Insight:** When an auth plugin delegates verification to a transport-provided status callback, audit every transport implementation of that callback: stub methods returning nil and servers built without the secret silently disable the check on encrypted transports.

