Skip to content

CoreDNS Loop Detection Denial of Service Vulnerability

High severity GitHub Reviewed Published Mar 6, 2026 in coredns/coredns

Package

gomod github.com/coredns/coredns (Go)

Affected versions

< 1.14.2

Patched versions

1.14.2

Description

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

// 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

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

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

References

@yongtang yongtang published to coredns/coredns Mar 6, 2026
Published by the National Vulnerability Database Mar 6, 2026
Published to the GitHub Advisory Database Mar 6, 2026
Reviewed Mar 6, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(64th percentile)

Weaknesses

Predictable Seed in Pseudo-Random Number Generator (PRNG)

A Pseudo-Random Number Generator (PRNG) is initialized from a predictable seed, such as the process ID or system time. Learn more on MITRE.

CVE ID

CVE-2026-26018

GHSA ID

GHSA-h75p-j8xm-m278

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.