See how coredns compares to other vendors in security performance
CoreDNS is a DNS server written in Go. Prior to 1.14.7, the DNS-over-HTTPS, DNS-over-HTTP/3, DNS-over-QUIC, and DNS-over-gRPC listeners in plugin/pkg/doh/doh.go, core/dnsserver/serverquic.go, and core/dnsserver/servergrpc.go call dns.Msg.Unpack without the dns.DefaultMsgAcceptFunc request policy used by UDP, TCP, and DNS-over-TLS. An unauthenticated client can send an RFC 2136 UPDATE that the proxy or forward plugin passes unchanged to an update-capable upstream. If that upstream trusts CoreDNS's source address or connection and does not require an attacker-unknown end-to-end TSIG, the request appears to originate from CoreDNS and can add, replace, or delete DNS records, redirect traffic, take over names, alter mail routing, or disrupt the writable zone. This issue is fixed in version 1.14.7.
CoreDNS is a DNS server written in Go. Prior to 1.14.5, the CoreDNS rewrite plugin supports edns0 rewrite rules with an optional revert flag, and two response rules, edns0SetResponseRule and edns0ReplaceResponseRule[T] in plugin/rewrite/edns0.go, call res.IsEdns0() and immediately dereference the returned dns.OPT without a nil check when a downstream plugin returns a response with no OPT record. A remote, unauthenticated client can send a single ordinary DNS query matching a rewrite edns0 <local|nsid|subnet> <set|append|replace> ... revert rule, causing ResponseReverter in plugin/rewrite/reverter.go to panic, return SERVFAIL, and degrade availability, or crash the CoreDNS process if the debug directive disables recovery. This issue is fixed in version 1.14.5.
CoreDNS is a DNS server written in Go. Prior to 1.14.4, a single 28-byte UDP datagram can crash the CoreDNS process when the proxyproto plugin is enabled because plugin/pkg/proxyproto/proxyproto.go PacketConn.ReadFrom handles a PROXY v2 header with non-UDP transport such as family byte 0x11, reassigns addr from a nil readFrom result after parseProxyProtocol errors, and calls addr.String() in the warning log before ServeDNS recovery applies. This issue is fixed in version 1.14.4.
CoreDNS k8sexternal headless AXFR can emit an empty transfer batch that panics the transfer plugin
CoreDNS is a DNS server written in Go. In versions prior to 1.14.3, the gRPC, QUIC, DoH, and DoH3 transport implementations incorrectly handle TSIG authentication. For gRPC and QUIC, the server checks whether the TSIG key name exists in the configuration but never calls dns.TsigVerify() to validate the HMAC. If the key name matches a configured key, the tsigStatus field remains nil and the tsig plugin treats the request as successfully authenticated regardless of the MAC value. For DoH and DoH3, the issue is more severe: the DoHWriter.TsigStatus() method unconditionally returns nil, and the server never inspects the TSIG record at all. Any request containing a TSIG record is treated as authenticated over DoH and DoH3, even if the key name is invalid and the MAC is arbitrary.
An unauthenticated network attacker can exploit this to bypass TSIG-protected functionality such as AXFR/IXFR zone transfers, dynamic DNS updates, or other TSIG-gated plugin behavior. The DoH and DoH3 variants have a lower exploitation bar because the attacker does not need to know a valid TSIG key name.
This issue has been fixed in version 1.14.3. As a workaround, disable gRPC, QUIC, DoH, and DoH3 listeners where TSIG authentication is required, or restrict network-level access to affected transport ports to trusted sources only.
CoreDNS is a DNS server that chains plugins. Prior to version 1.14.2, a denial of service vulnerability exists in CoreDNS's loop detection plugin that allows an attacker to crash the DNS server by sending specially crafted DNS queries. The vulnerability stems from the use of a predictable pseudo-random number generator (PRNG) for generating a secret query name, combined with a fatal error handler that terminates the entire process. This issue has been patched in version 1.14.2.
CoreDNS is a DNS server that chains plugins. Prior to version 1.14.2, a logical vulnerability in CoreDNS allows DNS access controls to be bypassed due to the default execution order of plugins. Security plugins such as acl are evaluated before the rewrite plugin, resulting in a Time-of-Check Time-of-Use (TOCTOU) flaw. This issue has been patched in version 1.14.2.
A logical vulnerability in CoreDNS allows DNS access controls to be bypassed due to the default execution order of plugins. Security plugins such as acl are evaluated before the rewrite plugin, resulting in a Time-of-Check Time-of-Use (TOCTOU) flaw.
Impact
In multi-tenant Kubernetes clusters, this flaw undermines DNS-based segmentation strategies.
Example scenario: 1. ACL blocks access to .admin.svc.cluster.local 2. A rewrite rule maps public-name → admin.svc.cluster.local 3. An unprivileged pod queries public-name 4. ACL allows the request 5. Rewrite exposes the internal admin service IP
This allows unauthorized service discovery and reconnaissance of restricted internal infrastructure.
Patches Has the problem been patched? What versions should users upgrade to?
Workarounds
- Reorder the default plugin.cfg so that: - rewrite and other normalization plugins run before acl, opa, and firewall - Ensure all access control checks are applied after name normalization.
Executive Summary
A Denial of Service vulnerability exists in CoreDNS's loop detection plugin that allows an attacker to crash the DNS server by sending specially crafted DNS queries. The vulnerability stems from the use of a predictable pseudo-random number generator (PRNG) for generating a secret query name, combined with a fatal error handler that terminates the entire process.
--- Technical Details
Vulnerability Description
The CoreDNS loop plugin is designed to detect forwarding loops by performing a self-test during server startup. The plugin generates a random query name (qname) using Go's math/rand package and sends an HINFO query to itself. If the server receives multiple matching queries, it assumes a forwarding loop exists and terminates.
The vulnerability arises from two design flaws:
1. Predictable PRNG Seed: The random number generator is seeded with time.Now().UnixNano(), making the generated qname predictable if an attacker knows the approximate server start time.
2. Fatal Error Handler: When the plugin detects what it believes is a loop (3+ matching HINFO queries), it calls log.Fatalf() which invokes os.Exit(1), immediately terminating the process without cleanup or recovery.
Affected Code
File: plugin/loop/setup.go go // PRNG seeded with predictable timestamp var r = rand.New(time.Now().UnixNano())
// Qname generation using two consecutive PRNG calls func qname(zone string) string { l1 := strconv.Itoa(r.Int()) l2 := strconv.Itoa(r.Int()) return dnsutil.Join(l1, l2, zone) }
File: plugin/loop/loop.go go func (l Loop) ServeDNS(ctx context.Context, w dns.ResponseWriter, r dns.Msg) (int, error) { // ... validation checks ... if state.Name() == l.qname { l.inc() // Increment counter }
if l.seen() > 2 { // FATAL: Terminates entire process log.Fatalf("Loop (%s -> %s) detected for zone %q...", ...) } // ... }
File: plugin/pkg/log/log.go go func Fatalf(format string, v ...any) { logf(fatal, format, v...) os.Exit(1) // Immediate process termination }
Exploitation Window
The loop plugin remains active during the following conditions:
| Condition | Window Duration | Attack Feasibility | |-----------|-----------------|-------------------| | Healthy startup | 2 seconds | Requires precise timing | | Self-test failure (upstream unreachable) | 30 seconds | HIGH - Extended window | | Network degradation | Variable | Depends on retry behavior |
Attack Scenario
Primary Attack Vector: Network Degradation
When the upstream DNS server is unreachable (network partition, misconfiguration, outage), the loop plugin's self-test fails repeatedly. During this period:
1. The loop plugin remains active for up to 30 seconds 2. Each self-test attempt generates an HINFO query visible in CoreDNS logs 3. An attacker with log access (shared Kubernetes cluster, centralized logging) can observe the qname 4. The attacker sends 3 HINFO queries with the observed qname 5. The server immediately crashes
┌──────────────────────────────────────────────────────────────────────────┐ │ ATTACK TIMELINE │ ├──────────────────────────────────────────────────────────────────────────┤ │ T+0s CoreDNS starts, PRNG seeded with UnixNano() │ │ T+0.5s Self-test HINFO query sent (visible in logs) │ │ T+2s Self-test fails (upstream timeout) │ │ T+3s Retry #1 - counter resets, qname unchanged │ │ T+5s Retry #2 - attacker observes qname in logs │ │ T+5.1s ATTACKER: Send HINFO #1 → counter = 1 │ │ T+5.2s ATTACKER: Send HINFO #2 → counter = 2 │ │ T+5.3s ATTACKER: Send HINFO #3 → counter = 3 → os.Exit(1) │ │ T+5.3s SERVER CRASHES │ └──────────────────────────────────────────────────────────────────────────┘
---
Impact Assessment
Attack Requirements
| Requirement | Notes | |-------------|-------| | Network Access | Must be able to send UDP packets to CoreDNS port | | Log Access | Required to observe the qname (common in shared clusters) | | Timing | Extended window during network degradation | | Authentication | None required |
Real-World Impact
CoreDNS is the default DNS server for Kubernetes clusters. A successful attack would:
1. Disruption: All DNS resolution fails within the cluster 2. Cascading Failures: Services unable to discover each other 3. Restart Loop: If attack persists, CoreDNS enters crash-restart cycle 4. Data Plane Impact: Application-level failures across the cluster
References
- CoreDNS GitHub: https://github.com/coredns/coredns - Loop Plugin Documentation: https://coredns.io/plugins/loop/ - Go math/rand Documentation: https://pkg.go.dev/math/rand
Summary
A Denial of Service (DoS) vulnerability was discovered in the CoreDNS DNS-over-QUIC (DoQ) server implementation. The server previously created a new goroutine for every incoming QUIC stream without imposing any limits on the number of concurrent streams or goroutines. A remote, unauthenticated attacker could open a large number of streams, leading to uncontrolled memory consumption and eventually causing an Out Of Memory (OOM) crash — especially in containerized or memory-constrained environments.
Impact
- Component: serverquic.go - Attack Vector: Remote, network-based - Attack Complexity: Low - Privileges Required: None - User Interaction: None - Impact: High availability loss (OOM kill or unresponsiveness)
This issue affects deployments with quic:// enabled in the Corefile. A single attacker can cause the CoreDNS instance to become unresponsive using minimal bandwidth and CPU.
Patches
The patch introduces two key mitigation mechanisms:
- maxstreams: Caps the number of concurrent QUIC streams per connection. Default: 256. - workerpoolsize: Introduces a server-wide, bounded worker pool to process incoming streams. Default: 1024.
This eliminates the 1:1 stream-to-goroutine model and ensures that CoreDNS remains resilient under high concurrency. The new configuration options are exposed through the quic Corefile block:
quic { maxstreams 256 workerpoolsize 1024 }
These defaults are generous and aligned with typical DNS-over-QUIC client behavior.
Workarounds
If you're unable to upgrade immediately, you can: - Disable QUIC support by removing or commenting out the quic:// block in your Corefile - Use container runtime resource limits to detect and isolate excessive memory usage - Monitor QUIC connection patterns and alert on anomalies
References
- RFC 9250 - DNS over Dedicated QUIC Connections - quic-go GitHub project - QUIC stream exhaustion class of vulnerabilities (related)
Credit
Thanks to @thevilledev for disclovering this vulnerability and contributing a high-quality fix.
For more information
Please consult our security guide for more information regarding our security process.
Coredns mishandling of CI bit: CD bit response is cached and served later
What happened: If CD bit is set in query, it disables validation at remote server
What you expected to happen: CD queries may pass, but the same answer must not be served to queries without CD bit set
https://github.com/coredns/coredns/issues/6186