HOL LogoGuard

Explore HOL

  • HOL home
  • AI agent registry
  • AI plugins
  • Open standards
  • HOL members
  • Sponsor HOL
  • Advertise with HOL

Guard product

  • Guard overviewLocal security and control for AI agents and the tools they use.
  • FeaturesRuntime protection, policy routing, review, and evidence.

Explore Guard

  • Product previewWalk through Guard surfaces in read-only demo mode.
  • ComparisonCompare Guard with native controls and AI security vendors.

AI tools

  • All AI toolsEvery supported AI tool and how Guard applies policy to it.
  • Codex
  • Claude Code
  • Cursor
  • Antigravity CLI
  • OpenCode
  • Hermes
  • OpenClaw
  • GitHub Copilot CLI
  • Antigravity
  • Kimi
  • Grok
  • Pi / Oh My Pi
  • Zcode

Extensions

  • All extensionsBrowse command and MCP coverage with owners and stated limits.
  • Command coverageShell command protection across clouds, databases, backups, and packages.
  • MCP server coverageSee how Guard maps risk state across MCP tools and servers.
  • Core safetyThe safety floor listings that ship with Guard.
  • Data and resilienceBackup and storage command protection.
  • Cloud and infrastructureAWS, Azure, GCP, Kubernetes, and more.

Security

  • AI security hubSecurity research, advisories, and agent safety coverage.
  • AI tool securitySecurity profiles for each supported coding agent.
  • Safe labsHands-on attack simulations with safe boundaries.
  • Redacted warningsReal blocked actions with sensitive details removed.
  • AdvisoriesCoordinated disclosure reports for AI tooling.
  • Active CVEsSearch active CVEs affecting AI tooling.

Learn

  • Security guidesPractical guides for securing AI agent workflows.
  • DocsInstall, configure, and operate Guard with confidence.
  • ResearchPublished security research, benchmarks, and methodology.

Community

  • ReleasesVersion history, shipped changes and upgrade notes.
  • ContributorsThe people and contributions behind HOL Guard.
  • AffiliatesShare Guard with your audience and earn from referrals.
  • SponsorFund agreed research, implementation and shared testing through the HOL Partner Program.
  • AdvertiseCompare README logo placements, previews and monthly prices, or promote a plugin or extension.
PricingEnterpriseOpen AppInstall Guard
  1. Guard
  2. Security
  3. CVEs
  4. CVE 2026 62994 coredns k8sexternal headless axfr can emit an
HOL Guard

Public security guidance for teams protecting AI harnesses, MCP servers, skills, prompts, and local tool execution.

Install Guard

AI Security

  • Prompt injection
  • MCP security
  • OWASP MCP mapping
  • Supply chain

Resources

  • Trust packet
  • Harness setup
  • Redacted warnings
  • Safe labs

Product

  • Install Guard
  • Pricing
  • Open dashboard
Guard
  • Guard Overview
  • Releases
  • Contributors
  • Install Guard
  • Pricing
Docs
  • Documentation Index
  • Developer Hub
  • API Reference
  • Root OpenAPI
  • Registry OpenAPI
  • Run in Postman
  • Standards
  • Submit ERC-8004 Contract
  • Feature Your Agent
Best Plugins
  • Browse Plugins
  • Plugin Launches
  • Best Claude Plugins
  • Best Codex Plugins
  • Best Grok Plugins
  • Best Kimi Plugins
  • Best DeepSeek Plugins
  • Best Antigravity Plugins
  • Best MCP Servers
  • Best Cursor Plugins
  • Best OpenCode Plugins
Best Agents
  • Best ERC-8004 Agents
  • Best Virtuals Agents
  • Best MCP Servers
  • Best A2A Agents
  • Best x402 Payable
  • All Categories
Community
  • Telegram
  • X
More
  • About HOL
  • Sponsor
  • Advertise
  • Contact
  • Blog
  • GitHub
  • Privacy
  • Terms of Service
Settings

Copyright © 2026 HOL DAO LLC. All rights reserved.

Back to active CVEs
Low · CVSS 3.7CVE-2026-62994GHSA-74W3-63XV-X9MV

CoreDNS `k8s_external` headless AXFR can emit an empty transfer batch that panics the `transfer` pluginCVE-2026-62994

Answer in brief

CVE-2026-62994 records a Low severity (CVSS 3.7) vulnerability in CoreDNS `k8s_external` headless AXFR can emit an empty transfer batch that panics the `transfer` plugin. The current sources do not mark it as known exploited. The current feed maps github.com/coredns/coredns (go). Check affected ranges and fixed versions before updating.

Analysis pending evidence review

HOL Guard separates source facts from reviewed analysis. See the methodology.

Published Jul 16, 2026Updated Oct 16, 2026Source checked Oct 16, 2026First seen by HOL Jul 17, 2026Material review Oct 16, 2026
Upstream Advisory

Record context

Vulnerability class
Vulnerability
EPSS
Not reported
CWE IDs
CWE-248, CWE-755
Source
GitHub Security Advisories
Source checked
Oct 16, 2026
References
6 linked sources
Open source record

Key facts

Risk
Low · CVSS 3.7
Exploitation
Not marked as known exploited
Affected software
1 mapped package or product
Fix availability
Available

Why this deserves its current priority

CVSS is 3.7. The current sources do not mark it as known exploited. Treat this as a source-backed prioritization signal, not a statement about your environment.

Analysis status

Analysis pending evidence review

Factual feed record only; HOL analysis is not approved for indexing. Read the methodology.

Affected scope and exposure questions

The current feed maps github.com/coredns/coredns (go). Check affected ranges and fixed versions before updating.

Mapped affected packages and fixed versions
PackageAffected rangeFixed version
github.com/coredns/corednsgo>=1.9.4,<=1.14.41.14.5

Recommended response

  1. 1Check inventory. Check lockfiles and deployed manifests for github.com/coredns/coredns.
  2. 2Review the reported fix. Update github.com/coredns/coredns to 1.14.5 if you use the affected versions. Test the change in a non-production environment first.

Evidence timeline and material changes

  1. Published upstream

    Jul 16, 2026

    Evidence: source:ghsa:source_dates:source-dates:record
  2. Source modified

    Oct 16, 2026

    Evidence: source:ghsa:source_dates:source-dates:record
  3. First seen by HOL

    Jul 17, 2026

Sources and claim methodology

  • GitHub security advisorygithub.com
  • GitHub security advisorygithub.com
  • GitHub security advisorygithub.com
  • GitHub security advisorygithub.com
  • GitHub security advisorygithub.com
  • NVD vulnerability recordnvd.nist.gov
Upstream source description

### Summary A network DNS client allowed to request AXFR for a CoreDNS zone can trigger a panic when CoreDNS is configured with `k8s_external` headless-service zone transfers and Kubernetes contains a headless service endpoint with no declared ports. The built-in `k8s_external` transferer can emit an empty `[]dns.RR` batch, and the shared `transfer` plugin indexes `records[0]` without checking that the batch is non-empty. In normal CoreDNS mode the panic is recovered and returned as `SERVFAIL`, but repeated triggering can disrupt requests and amplify panic logging; if the `debug` plugin disables recovery, the same path can crash the CoreDNS process. ### Details `plugin/transfer/transfer.go` assumes that every `Transferer` emits only non-empty `[]dns.RR` batches. During AXFR/IXFR response generation it indexes `records[0]` without checking the slice length: - `plugin/transfer/transfer.go:129-131` ```go for records := range pchan { if x, ok := records[0].(*dns.SOA); ok && soa == nil { soa = x } ``` The built-in `k8s_external` transferer violates that contract for headless services whose endpoints have no declared ports. `plugin/k8s_external/transfer.go` sends the SRV result slice unconditionally: - `plugin/k8s_external/transfer.go:104-106` ```go recs, _ := e.srv(ctx, svcs, s) ch <- recs ``` `plugin/k8s_external/msg_to_dns.go` intentionally skips services whose port is `-1`: - `plugin/k8s_external/msg_to_dns.go:107-112` ```go for _, s := range services { // Don't add the entry if the port is -1 (invalid). The kubernetes plugin uses port -1 when a service/endpoint // does not have any declared ports. if s.Port == -1 { continue } ``` The Kubernetes EndpointSlice conversion creates that sentinel when an EndpointSlice has no ports: - `plugin/kubernetes/object/endpoint.go:62-66` ```go if len(ends.Ports) == 0 { // Add sentinel if there are no ports. e.Subsets[0].Ports = []EndpointPort{{Port: -1}} ``` This creates a built-in source-to-sink chain: 1. Kubernetes EndpointSlice has ready addresses and no ports. 2. CoreDNS `kubernetes` converts it to an endpoint with `Port: -1`. 3. `k8s_external` with `headless` includes that service in transfer data. 4. `k8s_external.Transfer` sends an empty SRV `[]dns.RR` batch. 5. `transfer.ServeDNS` indexes `records[0]` and panics. Suggested remediation: 1. In `plugin/transfer/transfer.go`, skip or reject empty `records` batches before indexing `records[0]`. 2. In `plugin/k8s_external/transfer.go`, only send `recs` when `len(recs) > 0` in the headless endpoint and port/protocol paths. 3. Add regression tests covering `Port: -1` headless services and empty transfer batches. Example consumer-side guard: ```go for records := range pchan { if len(records) == 0 { continue } if x, ok := records[0].(*dns.SOA); ok && soa == nil { soa = x } ... } ``` ### PoC Safe local unit-level reproduction was performed. It does not contact external infrastructure and does not require a live Kubernetes cluster. #### Reproducer A: the `transfer` sink panics on an empty batch A temporary package test was added under `plugin/transfer`: ```go package transfer import ( "context" "fmt" "testing" "github.com/coredns/coredns/plugin/pkg/dnstest" "github.com/coredns/coredns/plugin/test" "github.com/miekg/dns" ) type auditEmptyBatchTransferer struct{} func (auditEmptyBatchTransferer) Transfer(zone string, serial uint32) (<-chan []dns.RR, error) { if zone != "example.org." { return nil, ErrNotAuthoritative } ch := make(chan []dns.RR, 3) ch <- []dns.RR{test.SOA(fmt.Sprintf("%s 100 IN SOA ns.dns.%s hostmaster.%s %d 7200 1800 86400 100", zone, zone, zone, 1))} ch <- []dns.RR{} close(ch) return ch, nil } func TestAuditEmptyTransferBatchPanics(t *testing.T) { tr := &Transfer{ Transferers: []Transferer{auditEmptyBatchTransferer{}}, xfrs: []*xfr{{Zones: []string{"example.org."}, to: []string{"*"}}}, } req := new(dns.Msg) req.SetQuestion("example.org.", dns.TypeAXFR) rec := dnstest.NewRecorder(&test.ResponseWriter{TCP: true}) defer func() { if rec := recover(); rec == nil { t.Fatal("expected empty transfer batch to panic") } }() _, _ = tr.ServeDNS(context.Background(), rec, req) } ``` Verification command and result: ```text $ go test ./plugin/transfer -run TestAuditEmptyTransferBatchPanics -count=1 -v === RUN TestAuditEmptyTransferBatchPanics --- PASS: TestAuditEmptyTransferBatchPanics (0.00s) PASS ok github.com/coredns/coredns/plugin/transfer 0.005s ``` #### Reproducer B: the built-in `k8s_external` transferer emits the empty batch A temporary package test was added under `plugin/k8s_external`: ```go package external import ( "testing" "time" "github.com/coredns/coredns/plugin/etcd/msg" "github.com/coredns/coredns/plugin/kubernetes" "github.com/coredns/coredns/request" "github.com/miekg/dns" ) func TestAuditHeadlessNoPortTransferEmitsEmptyBatch(t *testing.T) { e := New() e.Zones = []string{"example.com."} e.headless = true e.externalAddrFunc = func(request.Request, bool) []dns.RR { return nil } e.externalSerialFunc = func(string) uint32 { return 1 } e.externalServicesFunc = func(string, bool) ([]msg.Service, map[string][]msg.Service) { return nil, map[string][]msg.Service{ "/coredns/com/example/testns/headless/" + kubernetes.Endpoint: {{Host: "192.0.2.10", Port: -1, TTL: 5, Key: "/coredns/com/example/testns/headless/endpoint-a"}}, } } ch, err := e.Transfer("example.com.", 0) if err != nil { t.Fatalf("Transfer returned error: %v", err) } deadline := time.After(time.Second) for { select { case batch, ok := <-ch: if !ok { t.Fatal("transfer closed before emitting an empty batch") } if len(batch) == 0 { return } case <-deadline: t.Fatal("timed out waiting for an empty batch") } } } ``` Verification command and result: ```text $ go test ./plugin/k8s_external -run TestAuditHeadlessNoPortTransferEmitsEmptyBatch -count=1 -v === RUN TestAuditHeadlessNoPortTransferEmitsEmptyBatch --- PASS: TestAuditHeadlessNoPortTransferEmitsEmptyBatch (0.00s) PASS ok github.com/coredns/coredns/plugin/k8s_external 0.012s ``` Additional focused verification: ```text $ go test ./plugin/transfer ./plugin/k8s_external ./plugin/kubernetes -run 'TestAudit|^$' -count=1 -v ok github.com/coredns/coredns/plugin/transfer 0.006s ok github.com/coredns/coredns/plugin/k8s_external 0.013s ok github.com/coredns/coredns/plugin/kubernetes 0.116s ``` Affected package suites: ```text $ go test ./plugin/transfer ./plugin/k8s_external ./plugin/kubernetes -count=1 ok github.com/coredns/coredns/plugin/transfer 0.010s ok github.com/coredns/coredns/plugin/k8s_external 0.011s ok github.com/coredns/coredns/plugin/kubernetes 0.194s ``` ### Impact A network client allowed to request AXFR for the affected zone can trigger a panic in CoreDNS when all prerequisites are present. Required configuration/state: ```corefile example.com:53 { kubernetes cluster.local k8s_external example.com { headless } transfer example.com { to * } } ``` Additional prerequisite: - The Kubernetes API state contains a headless-service endpoint represented by an EndpointSlice with ready addresses and no ports, producing CoreDNS `msg.Service{Port: -1}`. In normal CoreDNS mode, `core/dnsserver/server.go:267-279` recovers the panic and returns `SERVFAIL`, so this is a request-level availability issue and panic/log amplification issue. If the `debug` plugin is enabled, the server disables the recovery path and this can crash the CoreDNS process.

Quoted source text, attributed separately from HOL analysis.