DNS Benchmark ProReal-time DoH latency analysis

DNS Security

DNS Security Alert: One Request Crashes HTTP/3 Servers

By Nattapong Sukkasem · Published · Updated .

TL;DR — A class of flaws in QPACK, the header compression layer of HTTP/3, lets a remote unauthenticated client send tens of kilobytes and make a server allocate hundreds of megabytes. FoxIO found the pattern in seven of the ten HTTP/3 stacks it tested. quic-go, Cloudflare quiche, lsquic and Wireshark are fixed; Bun, the Rust h3 crate and aioquic were not when the research and its proof-of-concept went public on 20 October. The DNS security relevance is direct, because HTTP/3 is the transport underneath modern DNS over HTTPS: a resolver's QUIC library is now part of its attack surface.

Encrypted DNS spent a decade winning the privacy argument and quietly inherited a second one. Most DNS security discussion concerns who can read a query in flight. The research FoxIO published on 20 October is about what a server does when it decompresses one. Sébastien Féry's write-up, nicknamed Header Accordions, documents memory amplification bugs in QPACK — the header compression scheme HTTP/3 uses in place of HTTP/2's HPACK — with observed ratios running from roughly 15× to about 4,000× against default configurations.

DNS security: the entrance area of a Cloudflare office, the vendor whose quiche QUIC library was patched against the QPACK HTTP/3 memory amplification flaw affecting encrypted DNS server infrastructure
A Cloudflare office entrance, photographed in 2021. Cloudflare's quiche is one of the seven affected HTTP/3 stacks and was fixed in 0.29.3 on 14 July 2026 as CVE-2026-12523 — the highest-scored CVE in the set at CVSS 7.5.

How a one-byte reference becomes a megabyte

QPACK replaces repeated header fields with indexes into two tables: a static table fixed by the specification, and a dynamic table built up over the life of a connection. The compression is excellent, which is the problem. A single byte can stand for a 71-byte header. The h3 issue filed on 22 October gives a cleaner example still: the byte 0xfa references static entry 58, a strict-transport-security field that costs about 100 bytes once decoded.

Chain enough of those together and the arithmetic turns hostile. FoxIO reports a one-megabyte HEADERS block decoding into roughly 160,000 header fields and leaving about 15 MiB resident on quic-go. A second technique is worse: insert one entry of about 4 KiB on the encoder stream, then reference it thousands of times with one-byte indexes. Each reference forces a fresh allocation and a full copy of the entry, producing a measured 4,064:1 ratio.

The reason this survived in so many codebases is a consistent accounting error. Implementations bound the compressed frame rather than the decoded total; or they check the limit after decoding everything; or they omit RFC 9114's 32-byte per-field overhead; or the limit exists and defaults to unlimited. In the Rust h3 crate, max_field_section_size defaults to VarInt::MAX, so an incremental size check added in an earlier fix never fires on a default build — and past 32,768 fields the library panics outright inside http::HeaderMap.

Bun produces the most extreme failure. Its experimental HTTP/3 server substitutes its own check for lsquic's 64 KB cap, and that check tracks individual headers without a running total. Once unpacked headers pass 2 GB the size counter overflows to zero and the server loops indefinitely. One stream of roughly 516 KB on the wire left it pinned at 100% CPU with no recovery.

HTTP/3 stackStatusFix / identifierObserved amplification
quic-goFixed0.57.0 · CVE-2025-64702; trailers in 0.59.1 · CVE-2026-40898~15× retained heap
Cloudflare quicheFixed0.29.3 · CVE-2026-12523 (CVSS 7.5)~20×
lsquicFixed4.9.0, 15 July 2026 · no CVE600×–1,800×
WiresharkFixed4.6.2 / 4.4.12 · CVE-2025-13945Dissector crash
Bun 1.4.3UnpatchedAdvice: do not expose HTTP/3~4,000×, then infinite loop
h3 (hyperium, Rust)UnpatchedSet a finite max_field_section_sizePanic at 32,768 fields
aioquic / mitmproxyUnpatched--set http3=false20×–30×

FoxIO reports IIS, Envoy, ngtcp2/nghttp3 and Google's quiche as unaffected, because each caps unpacked headers during decoding rather than after.

The Cloudflare wordmark and logo, representing the quiche QUIC library patched for CVE-2026-12523, one of the QPACK DNS security flaws affecting HTTP/3 and DNS over HTTPS cloud security
Cloudflare shipped quiche 0.29.3 in July 2026. FoxIO's disclosure timeline runs from the first vendor report on 9 November 2025 to publication on 20 October 2026 — nearly a year of coordinated work before the details became public.

Why this reaches DNS over HTTPS and resolver infrastructure

No public reporting ties these flaws to any named public resolver, and nobody has reported exploitation in the wild. FoxIO's post does not discuss DNS at all. The connection is structural rather than incidental, and it is worth stating precisely.

DNS over HTTPS is, by definition, DNS carried inside HTTPS. HTTPS increasingly means HTTP/3, and any resolver endpoint advertising h3 in an Alt-Svc header is terminating QUIC and running a QPACK decoder against whatever arrives on UDP 443. Classic DNS on port 53 has no compression state to abuse and no per-connection decoder budget to overrun; the server's work per message is bounded and tiny. Encrypted transport changed that trade. It bought confidentiality and took on a stateful compression layer in which the client, not the server, decides how much memory the exchange will cost.

That matters more for resolution than for an ordinary web property, because resolver failures do not degrade gracefully. A browser that cannot reach one site tries another. A device pinned to a single encrypted resolver — the normal arrangement when a phone's Private DNS setting names one provider — stops resolving anything at all. This site made the same argument during the root zone KSK rollover: when the resolver is the failure point, the outcome is local, deterministic and total.

A Wireshark screenshot dissecting a DNS query packet through Ethernet, IP and UDP layers, the same dissector architecture whose HTTP/3 component crashes under the QPACK DNS security flaw
Wireshark applying its dissectors to an ordinary unencrypted DNS query on UDP port 53 — a bounded 74-byte message the server can answer without allocating on the client's instruction. The HTTP/3 dissector is the component affected by CVE-2025-13945: it crashes when decrypting QPACK traffic with a key-log file, which makes the analyst's own workstation — not a server — the casualty. Wireshark says it is unaware of any exploits.

Amplification without a single spoofed packet

A DDoS attack rents asymmetry from the network: the attacker buys bandwidth, reflects or spoofs it, and the imbalance shows up in every traffic graph the victim owns. Header Accordions inverts the economics. The amplifier is the server's own decoder, the ratio is up to 4,000:1, and the cost to the attacker is a single ordinary connection — no botnet, no reflection, nothing that reads as volume on a capacity dashboard.

Because HTTP/3 runs over UDP, those requests also arrive early, before much of the layer-7 inspection that organisations assume sits in front of an application. And the symptom does not look like a network outage: links stay up, network latency looks normal until the moment memory runs out, and the useful alert is the one most teams do not have — resident memory climbing steeply on an edge proxy while the request rate stays flat.

There is a cloud security consequence that cuts in the defender's favour for once. If a CDN or managed edge terminates HTTP/3 and speaks HTTP/1.1 or HTTP/2 to the origin, the origin never sees raw QPACK from the internet. The question is therefore not what runs your application but what terminates your QUIC, and for a great deal of server infrastructure the honest answer is a library two dependencies deep.

It is also worth being clear about what kind of risk this is. This is not a zero-day vulnerability; it is close to its opposite. The vendors were notified between November 2025 and July 2026, four of them shipped fixes, and the dangerous window opened on publication day, when working proof-of-concept code reached everyone at once while three implementations still had no patch. The disclosure was responsible. The exposure is now a race.

A network latency comparison of public DNS resolvers measured in the browser, the kind of baseline that reveals when an encrypted DNS endpoint stops answering
A resolver comparison run from the browser. A network latency baseline taken before an incident is what tells you whether an encrypted resolver has slowed, failed over, or stopped answering altogether.

What to check this week

  1. Establish whether you serve HTTP/3 at all. Look for h3 in an Alt-Svc response header and for listeners on UDP 443 (ss -ulpn | grep ':443'). Plenty of estates advertise it without anyone having decided to.
  2. Identify the library, not the product. go version -m on Go binaries, cargo tree -i quiche or -i h3 for Rust, pip show aioquic mitmproxy, bun --version, tshark --version. Check the artefact actually deployed, which may predate the manifest.
  3. Patch to the fixed builds. quic-go 0.57.0 and 0.59.1 for the trailers variant, quiche 0.29.3, lsquic 4.9.0, Wireshark 4.6.2 or 4.4.12.
  4. Where no fix exists, remove the exposure instead. Do not expose Bun's HTTP/3 server; disable HTTP/3 in mitmproxy; set a finite max_field_section_size on h3 — 64 KiB is the proposed default, against nginx's 32 KB and Envoy's 60 KiB.
  5. Alert on memory, not on requests. The IT security detection that works here is a resident-memory threshold per proxy process, because request counts and bandwidth stay unremarkable throughout.
  6. Know what your resolvers answer with, and keep a second one. A network diagnostic tool run from the affected network tells you what resolution looks like right now; how DoH actually works is worth re-reading before committing every client to one encrypted endpoint.
A DNS server performance benchmark measuring encrypted resolver response times from the browser, used to compare DoH endpoints before committing clients to one provider
A DNS server performance benchmark against public resolvers. Measuring several encrypted endpoints, rather than trusting one, is the cheapest redundancy available to an endpoint that resolves over HTTPS.

What it means

Compression is a server doing work on a client's instruction. Every format that lets a small input describe a large output — zip bombs, XML entity expansion, HPACK, now QPACK — eventually produces the same bug, and the fix is always the same shape: a cumulative budget, counted during decoding rather than checked afterwards, that includes the overhead of the structures being built. FoxIO's recommendation is exactly that, and it is notable that the implementations which got it right are the ones that enforce the cap mid-decode.

The wider lesson for DNS security is about what the move to encrypted transport actually imported. Running resolution over HTTPS did not simply add a TLS handshake to a UDP protocol; it moved DNS onto the web's protocol stack, with that stack's compression layers, its state machines, its dependency trees and its bug classes. HPACK had its header bomb. QPACK now has an accordion. The resolvers worth trusting will be the ones whose operators can say which QUIC library they run and when they last updated it — a question that was never on anyone's DNS security checklist a year ago, and belongs on it now.

Sources

Related articles

Browse every DNS news article by month →

DNS angle

Review resolver logs for the systems discussed above and compare unexpected names with your approved services. A successful lookup does not establish that a destination is safe. Use the DNS lookup tool to inspect current answers, then compare them with your own resolver and incident records.

Source: The Hacker News — New QPACK Flaws Can Crash HTTP/3 Servers, Trigger Up to 4,000-Fold Memory Amplification ().