{"schema_version":"1.7.5","id":"GHSA-qhmp-q7xh-99rh","published":"2026-04-28T22:46:15Z","modified":"2026-06-25T23:11:03.600779103Z","aliases":["CVE-2026-33190","GO-2026-5583"],"related":["CGA-vhv4-mm4h-98r2"],"summary":"CoreDNS has TSIG authentication bypass on DoT, DoH, DoH3, DoQ, and gRPC","details":"### Summary\nCoreDNS' 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.\n\n### Details\nThe tsig plugin decides whether an incoming TSIG was valid by consulting w.TsigStatus(): tsigStatus := w.TsigStatus(); if tsigStatus != nil { ... NOTAUTH ... } (plugin/tsig/tsig.go)\n\nTwo affected transports are shown directly in the PoC:\n- DoH: DoHWriter.TsigStatus() always returns nil (core/dnsserver/https.go), and the HTTP server passes unpacked DNS messages directly into the plugin chain.\n- 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).\n\nThe same transport-family bug pattern also appears on other transports:\n- DoH3 reuses the DoH writer path (core/dnsserver/server_https3.go -> core/dnsserver/https.go), so it inherits the same TsigStatus() == nil behavior.\n- DoQ uses DoQWriter.TsigStatus() error { return nil } (core/dnsserver/quic.go).\n- gRPC uses gRPCresponse.TsigStatus() error { return nil } (core/dnsserver/server_grpc.go).\n\nThe attached PoC was kept deliberately small (baseline TCP+DoT+DoH only) for convenience.\n\n### PoC\n1. Adjust COREDNS_BIN in the PoC to point at right path (see the top-level const definitions for tunables as well)\n2. Run python3 ./tsig-repro.py\n3. Expected output:\n*** Start CoreDNS ***\nCorefile: /tmp/vh-f001-tsig-doh-dot-bypass/Corefile\nLog: /tmp/vh-f001-tsig-doh-dot-bypass/coredns.log\n\n*** Baseline (plain TCP) ***\nno_tsig rcode=5 (expected REFUSED=5)\ninvalid_tsig rcode=9 (expected NOTAUTH=9)\n\n*** Candidate (DoT) ***\nno_tsig rcode=5 (expected REFUSED=5)\ninvalid_tsig rcode=0 ancount=1 (expected NOERROR=0 and ancount>0)\n\n*** Candidate (DoH) ***\nno_tsig http=200 rcode=5 (expected REFUSED=5)\ninvalid_tsig http=200 rcode=0 ancount=1 (expected NOERROR=0 and ancount>0)\n\n*** OK ***\nTSIG bypass reproduced: plain TCP rejects invalid TSIG, while DoT and DoH accept it.\nResults: /tmp/vh-f001-tsig-doh-dot-bypass/results.json\n\n\n### Impact\nUnauthenticated 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.).","affected":[{"package":{"name":"github.com/coredns/coredns","ecosystem":"Go","purl":"pkg:golang/github.com/coredns/coredns"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.14.3"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-qhmp-q7xh-99rh/GHSA-qhmp-q7xh-99rh.json"}}],"references":[{"type":"WEB","url":"https://github.com/coredns/coredns/security/advisories/GHSA-qhmp-q7xh-99rh"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-33190"},{"type":"PACKAGE","url":"https://github.com/coredns/coredns"},{"type":"WEB","url":"https://github.com/coredns/coredns/releases/tag/v1.14.3"}],"database_specific":{"cwe_ids":["CWE-287","CWE-303"],"github_reviewed":true,"github_reviewed_at":"2026-04-28T22:46:15Z","nvd_published_at":"2026-05-05T20:16:36Z","severity":"HIGH"},"severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"},{"type":"CVSS_V4","score":"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"}]}