Severity by source
Sources disagree (Low–High)CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Network-reachable auth bypass on encrypted transports with no privileges or interaction (AV:N/AC:L/PR:N/UI:N); exposes restricted zone data (C:H) with no confirmed integrity or availability impact.
vuln.today treats the vendor’s rating as authoritative. A higher third-party CVSS (e.g. CISA-ADP) is shown for transparency but does not drive the headline severity.
CVSS VectorVendor: https://github.com/coredns/coredns
Lifecycle Timeline
5DescriptionCVE.org
Summary
CoreDNS' tsig plugin can be bypassed on non-plain-DNS transports because it trusts the transport writer's TsigStatus() instead of performing verification itself. In the attached PoC, plain DNS/TCP correctly rejects an invalid TSIG (NOTAUTH), while the same invalid-TSIG request is accepted over DoT (tls://) and DoH (https://), allowing a client without the shared secret to satisfy require all. The same bug class affects DoH3, DoQ, and gRPC.
Details
The tsig plugin decides whether an incoming TSIG was valid by consulting w.TsigStatus(): tsigStatus := w.TsigStatus(); if tsigStatus != nil { ... NOTAUTH ... } (plugin/tsig/tsig.go)
Two affected transports are shown directly in the PoC:
- DoH: DoHWriter.TsigStatus() always returns nil (core/dnsserver/https.go), and the HTTP server passes unpacked DNS messages directly into the plugin chain.
- DoT: the TLS server builds a dns.Server without setting TsigSecret (core/dnsserver/server_tls.go), unlike plain DNS/TCP/UDP which sets TsigSecret: s.tsigSecret (core/dnsserver/server.go).
The same transport-family bug pattern also appears on other transports:
- DoH3 reuses the DoH writer path (core/dnsserver/server_https3.go -> core/dnsserver/https.go), so it inherits the same TsigStatus() == nil behavior.
- DoQ uses DoQWriter.TsigStatus() error { return nil } (core/dnsserver/quic.go).
- gRPC uses gRPCresponse.TsigStatus() error { return nil } (core/dnsserver/server_grpc.go).
The attached PoC was kept deliberately small (baseline TCP+DoT+DoH only) for convenience.
PoC
- Adjust COREDNS_BIN in the PoC to point at right path (see the top-level const definitions for tunables as well)
- Run python3 ./tsig-repro.py
- Expected output:
* Start CoreDNS * Corefile: /tmp/vh-f001-tsig-doh-dot-bypass/Corefile Log: /tmp/vh-f001-tsig-doh-dot-bypass/coredns.log
* Baseline (plain TCP) * no_tsig rcode=5 (expected REFUSED=5) invalid_tsig rcode=9 (expected NOTAUTH=9)
* Candidate (DoT) * no_tsig rcode=5 (expected REFUSED=5) invalid_tsig rcode=0 ancount=1 (expected NOERROR=0 and ancount>0)
* Candidate (DoH) * no_tsig http=200 rcode=5 (expected REFUSED=5) invalid_tsig http=200 rcode=0 ancount=1 (expected NOERROR=0 and ancount>0)
* OK * TSIG bypass reproduced: plain TCP rejects invalid TSIG, while DoT and DoH accept it. Results: /tmp/vh-f001-tsig-doh-dot-bypass/results.json
Impact
Unauthenticated remote clients can bypass TSIG-based authentication/authorization on first-class encrypted transports, enabling access to whatever the deployment intended to restrict behind tsig { require all } (e.g., zone data/privileged queries, etc.).
AnalysisAI
TSIG authentication bypass in CoreDNS before 1.14.3 lets unauthenticated remote clients defeat the tsig plugin's require all policy on every encrypted transport (DoT, DoH, DoH3, DoQ, and gRPC). Because the plugin trusts each transport writer's TsigStatus() rather than verifying the signature itself, transports that never populate a TSIG secret return a nil status and treat invalid or unsigned requests as authenticated, granting access to zone data or privileged queries the operator meant to restrict. Publicly available exploit code (a reproducer PoC) exists, but EPSS is low (0.07%, 21st percentile) and it is not on CISA KEV, so there is no confirmed active exploitation at time of analysis.
Technical ContextAI
CoreDNS is a widely used Go-based DNS server and the default cluster DNS for Kubernetes. Its tsig plugin enforces RFC 2845 Transaction SIGnature (TSIG) authentication, a shared-secret HMAC over DNS messages, to gate operations such as zone transfers and dynamic updates. The flaw is a CWE-287 (Improper Authentication) design error: the plugin reads w.TsigStatus() from the ResponseWriter and only rejects with NOTAUTH when it is non-nil. For plain DNS/UDP/TCP, core/dnsserver/server.go constructs the underlying miekg/dns server with TsigSecret: s.tsigSecret, so the library actually verifies the signature and populates status. The encrypted transports do not: the TLS server (server_tls.go) builds a dns.Server without TsigSecret, and the DoH (https.go), DoH3 (server_https3.go), DoQ (quic.go), and gRPC (server_grpc.go) writers hardcode TsigStatus() to return nil. As a result no verification ever occurs on those paths and any request satisfies require all. CPE pkg:go/github.com_coredns_coredns identifies the affected package.
RemediationAI
Vendor-released patch: upgrade to CoreDNS 1.14.3, which adds full TSIG verification across DoH (PR 8013), DoH3 (PR 8044), QUIC/DoQ (PR 8007), and gRPC (PR 8006), propagates TSIG secrets to the DoT server (PR 7928), and preserves TSIG status in gRPC (PR 7943); see https://github.com/coredns/coredns/releases/tag/v1.14.3 and advisory https://github.com/coredns/coredns/security/advisories/GHSA-qhmp-q7xh-99rh. If you cannot upgrade immediately, the concrete compensating control is to stop relying on TSIG as the authorization gate over encrypted transports: disable the DoT/DoH/DoH3/DoQ/gRPC listeners in your Corefile and serve TSIG-gated functions (e.g. zone transfers) only over plain DNS/TCP where verification works - the trade-off is loss of transport encryption. Alternatively, place the affected listeners behind a network ACL or mTLS-terminating proxy and restrict the sensitive endpoints (AXFR/dynamic update) to known client IPs, accepting the operational cost of maintaining allowlists rather than trusting TSIG. Do not treat TSIG require all on encrypted transports as an authentication boundary until patched.
Same weakness CWE-287 – Improper Authentication
View allSame technique Authentication Bypass
View allVendor StatusVendor
SUSE
| Product | Status |
|---|---|
| openSUSE Tumbleweed | Fixed |
Share
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-27444
GHSA-qhmp-q7xh-99rh