GHSA-H75P-J8XM-M278

Vulnerability from github – Published: 2026-03-06 22:08 – Updated: 2026-03-06 22:08
VLAI?
Summary
CoreDNS Loop Detection Denial of Service Vulnerability
Details

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

  • 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
Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/coredns/coredns"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "1.14.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-26018"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-337"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-06T22:08:22Z",
    "nvd_published_at": "2026-03-06T16:16:10Z",
    "severity": "HIGH"
  },
  "details": "## Executive Summary\n\nA Denial of Service vulnerability exists in CoreDNS\u0027s 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.\n\n---\n## Technical Details\n\n### Vulnerability Description\n\nThe 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\u0027s `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.\n\n**The vulnerability arises from two design flaws:**\n\n1. **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.\n\n2. **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.\n\n### Affected Code\n\n**File: `plugin/loop/setup.go`**\n```go\n// PRNG seeded with predictable timestamp\nvar r = rand.New(time.Now().UnixNano())\n\n// Qname generation using two consecutive PRNG calls\nfunc qname(zone string) string {\n    l1 := strconv.Itoa(r.Int())\n    l2 := strconv.Itoa(r.Int())\n    return dnsutil.Join(l1, l2, zone)\n}\n```\n\n**File: `plugin/loop/loop.go`**\n```go\nfunc (l *Loop) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {\n    // ... validation checks ...\n    \n    if state.Name() == l.qname {\n        l.inc()  // Increment counter\n    }\n\n    if l.seen() \u003e 2 {\n        // FATAL: Terminates entire process\n        log.Fatalf(\"Loop (%s -\u003e %s) detected for zone %q...\", ...)\n    }\n    \n    // ...\n}\n```\n\n**File: `plugin/pkg/log/log.go`**\n```go\nfunc Fatalf(format string, v ...any) {\n    logf(fatal, format, v...)\n    os.Exit(1)  // Immediate process termination\n}\n```\n\n### Exploitation Window\n\nThe loop plugin remains active during the following conditions:\n\n| Condition | Window Duration | Attack Feasibility |\n|-----------|-----------------|-------------------|\n| Healthy startup | 2 seconds | Requires precise timing |\n| Self-test failure (upstream unreachable) | 30 seconds | **HIGH** - Extended window |\n| Network degradation | Variable | Depends on retry behavior |\n\n### Attack Scenario\n\n**Primary Attack Vector: Network Degradation**\n\nWhen the upstream DNS server is unreachable (network partition, misconfiguration, outage), the loop plugin\u0027s self-test fails repeatedly. During this period:\n\n1. The loop plugin remains active for up to 30 seconds\n2. Each self-test attempt generates an HINFO query visible in CoreDNS logs\n3. An attacker with log access (shared Kubernetes cluster, centralized logging) can observe the qname\n4. The attacker sends 3 HINFO queries with the observed qname\n5. The server immediately crashes\n\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502                         ATTACK TIMELINE                                  \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 T+0s     CoreDNS starts, PRNG seeded with UnixNano()                     \u2502\n\u2502 T+0.5s   Self-test HINFO query sent (visible in logs)                    \u2502\n\u2502 T+2s     Self-test fails (upstream timeout)                              \u2502\n\u2502 T+3s     Retry #1 - counter resets, qname unchanged                      \u2502\n\u2502 T+5s     Retry #2 - attacker observes qname in logs                      \u2502\n\u2502 T+5.1s   ATTACKER: Send HINFO #1 \u2192 counter = 1                           \u2502\n\u2502 T+5.2s   ATTACKER: Send HINFO #2 \u2192 counter = 2                           \u2502\n\u2502 T+5.3s   ATTACKER: Send HINFO #3 \u2192 counter = 3 \u2192 os.Exit(1)              \u2502\n\u2502 T+5.3s   SERVER CRASHES                                                  \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n---\n\n## Impact Assessment\n\n### Attack Requirements\n\n| Requirement | Notes |\n|-------------|-------|\n| Network Access | Must be able to send UDP packets to CoreDNS port |\n| Log Access | Required to observe the qname (common in shared clusters) |\n| Timing | Extended window during network degradation |\n| Authentication | None required |\n\n### Real-World Impact\n\nCoreDNS is the default DNS server for Kubernetes clusters. A successful attack would:\n\n1. **Disruption**: All DNS resolution fails within the cluster\n2. **Cascading Failures**: Services unable to discover each other\n3. **Restart Loop**: If attack persists, CoreDNS enters crash-restart cycle\n4. **Data Plane Impact**: Application-level failures across the cluster\n\n## References\n\n- CoreDNS GitHub: https://github.com/coredns/coredns\n- Loop Plugin Documentation: https://coredns.io/plugins/loop/\n- Go math/rand Documentation: https://pkg.go.dev/math/rand",
  "id": "GHSA-h75p-j8xm-m278",
  "modified": "2026-03-06T22:08:22Z",
  "published": "2026-03-06T22:08:22Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/coredns/coredns/security/advisories/GHSA-h75p-j8xm-m278"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-26018"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/coredns/coredns"
    },
    {
      "type": "WEB",
      "url": "https://github.com/coredns/coredns/releases/tag/v1.14.2"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "CoreDNS Loop Detection Denial of Service Vulnerability"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.


Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…