• Severity: CVSS 8.8 (High - CISA-ADP scored; NVD assessment pending)
  • Affected: Apache HTTP Server 2.4.66 with mod_http2 enabled under multi-threaded MPM (event/worker)
  • Patched: May 4, 2026 (Apache 2.4.67) · Exploitation: DoS confirmed in the wild; public PoC available; RCE demonstrated in lab

Introduction

CVE-2026-23918 was disclosed on May 4, 2026 as part of the Apache HTTP Server 2.4.67 security release. It resides in mod_http2, specifically in the stream cleanup path of h2_mplx.c, and is classified as a Double Free (CWE-415). The vulnerability was discovered and responsibly reported in December 2025 by Bartłomiej Dmitruk of Striga.ai and Stanisław Strzałkowski of ISEC.pl, with a working RCE proof-of-concept included in the disclosure package.

The conditions required for exploitation are minimal: an HTTP/2 request over any default Apache deployment using a multi-threaded MPM. No authentication is needed, no specific URL must exist, and no special headers are required. The DoS path is completely trivial. The RCE path is constrained to deployments where the Apache Portable Runtime (APR) uses the mmap allocator, which is the default on Debian-derived Linux distributions and on the official httpd Docker image.

MPM prefork (the single-process, single-threaded model) is not affected. Apache HTTP Server versions prior to 2.4.66 are also not affected, this bug was introduced specifically in 2.4.66.

Given the ubiquity of Apache, the fact that mod_http2 ships enabled by default in most builds, and the public availability of working PoC tooling, this should be treated as an emergency patch priority for any deployment running 2.4.66.


What Happened

The root cause is a race condition flaw in how mod_http2 handles early stream resets. Apache’s HTTP/2 implementation in h2_mplx.c tracks active streams using internal h2_stream objects. The bug triggers when a client sends an HTTP/2 HEADERS frame immediately followed by a RST_STREAM frame with a non-zero error code on the same stream, timed so that this arrives before the multiplexer has fully registered the stream.

When that happens, two separate nghttp2 callbacks fire in sequence: on_frame_recv_cb (handling the RST) and on_stream_close_cb (handling the stream close). Both callbacks independently call the same cleanup chain, h2_mplx_c1_client_rstm_stream_cleanup, and both push the same h2_stream pointer onto the cleanup (spurge) array. When c1_purge_streams later iterates that array and calls h2_stream_destroyapr_pool_destroy on each entry, the second call operates on memory that has already been freed. That is the double-free.

The immediate outcome is a worker process crash (SIGSEGV). Apache respawns the worker automatically, but the pattern can be sustained indefinitely, one connection, two frames, repeated, making the DoS both trivial and persistent.

CVE-2026-23918 Exploit Chain Overview

Fig 1: Exploit Chain Overview - from malformed HEADERS+RST_STREAM to double-free and worker crash


Attack Sequence

The DoS requires no setup. An attacker opens a single TLS (or plain TCP, if the server permits) connection to any Apache 2.4.66 server running mod_http2 with a multi-threaded MPM. They send one HTTP/2 HEADERS frame immediately followed by a RST_STREAM frame, no authentication, no specific endpoint, no crafted headers needed. Both frames arrive before the multiplexer registers the stream, the two cleanup callbacks race and both enqueue the same pointer, and when the purge runs the second apr_pool_destroy corrupts the heap. The worker crashes.

Apache respawns the dead worker but drops every in-flight request it was handling at the moment of the crash. As long as an attacker keeps sending the two-frame sequence, workers crash faster than they can recover, effectively taking the server offline. Researchers confirmed this is reliable on any default deployment within roughly 30 seconds to 3 minutes, depending on worker count and timing.

The RCE path requires additional conditions. The APR mmap allocator must be active, the default on Debian-based distributions and the official Apache httpd Docker image. With that allocator, the freed virtual address is eligible for reuse through mmap. An attacker places a fake h2_stream struct at that freed address, with its pool->cleanups function pointer replaced by a pointer to system(). Apache’s scoreboard shared memory, which resides at a fixed address for the lifetime of the server process regardless of ASLR, is used as a stable container for the fake structures and the command string. Because the scoreboard address is predictable, the technique partially defeats ASLR. An additional information leak is required to recover the address of system() and precise scoreboard offsets; the heap spray to land the fake struct is probabilistic. In lab conditions, the researchers achieved code execution within minutes on x86_64.

CVE-2026-23918 Attack Sequence

Fig 2: Attack Sequence - HTTP/2 frame timing, callback race, double-free, and optional RCE chain


Why This Is Especially Dangerous

This isn’t a theoretical severity score. The threat profile here is unusually broad:

  • Zero authentication, zero targeting - one connection, two frames is all the DoS takes. No credentials, no specific endpoints, no enumeration required.
  • Massive default exposure - mod_http2 ships enabled by default in most Apache builds; HTTP/2 is widely enabled in production. The attack surface is enormous.
  • Containerised workloads are in the RCE risk category - the official Apache Docker image uses the APR mmap allocator, which enables the RCE path. Any containerised service using the standard httpd image on version 2.4.66 is in scope.
  • Debian/Ubuntu servers face higher risk - the mmap allocator is the default on Debian-derived distros, meaning a large share of production Linux Apache deployments can be pushed from DoS to RCE under the right conditions.
  • ASLR is only partially effective - the scoreboard’s fixed lifetime address gives attackers a stable anchor, reducing but not eliminating the probabilistic nature of the heap spray.
  • Public PoC is available - multiple PoC implementations targeting both DoS and passive RCE detection are publicly available on GitHub as of May 2026. The barrier to exploitation is low.
  • APT weaponisation is expected - no attribution to specific threat actors has been confirmed yet, but the simplicity of the DoS and the value of the RCE make this attractive to ransomware operators, botnet controllers, and nation-state actors.

Affected Versions

BranchVulnerable VersionsFix Available
Apache HTTP Server 2.42.4.66 only2.4.67 (May 4, 2026)

Not affected:

  • Apache HTTP Server 2.4.65 and earlier
  • Any deployment using MPM prefork (single-threaded; the bug requires multi-threaded MPM)
  • Deployments where mod_http2 is disabled (no HTTP/2 enabled)

Ubuntu-specific patched package versions (per USN-8239-1):

Ubuntu ReleasePatched Package Version
26.04 LTS (Resolute)apache2 2.4.66-2ubuntu2.1
25.10 (Questing)apache2 2.4.64-1ubuntu3.4
24.04 LTS (Noble)apache2 2.4.58-1ubuntu8.12
22.04 LTS (Jammy)apache2 2.4.52-1ubuntu4.20

Note: CVE-2026-23918 specifically affects only Ubuntu 26.04 LTS (which ships 2.4.66). The remaining Ubuntu releases received the broader USN-8239-1 advisory update but are not vulnerable to this specific CVE.


Mitigations

1. Upgrade to Apache HTTP Server 2.4.67 immediately

This is the only complete fix. The patch corrects the stream ownership tracking in h2_mplx.c to prevent the double enqueue. All deployments running 2.4.66 should treat this as an emergency update.

# Debian/Ubuntu
sudo apt update && sudo apt install apache2

# RHEL/CentOS - monitor Red Hat advisory for package availability
sudo dnf update httpd

# Docker - pull the updated official image
docker pull httpd:latest
# Verify the version
docker run --rm httpd:latest httpd -v

2. Disable mod_http2 (interim workaround if patching is delayed)

Disabling the HTTP/2 module eliminates the attack surface for CVE-2026-23918 entirely. This degrades HTTP/2 performance but stops both the DoS and RCE paths.

In your Apache configuration (/etc/apache2/apache2.conf or the relevant virtual host file):

# Option A: Remove h2 from the Protocols directive
Protocols http/1.1

# Option B: Comment out or remove the mod_http2 LoadModule line
# LoadModule http2_module modules/mod_http2.so

Restart Apache after the change: sudo systemctl restart apache2

3. Switch to MPM prefork (alternative workaround)

If your workload can tolerate prefork’s performance characteristics, switching to the single-threaded MPM eliminates the vulnerability:

sudo a2dismod mpm_event
sudo a2dismod mpm_worker
sudo a2enmod mpm_prefork
sudo systemctl restart apache2

4. Rate-limit and restrict inbound HTTP/2 traffic

For deployments behind a WAF or reverse proxy: block or rate-limit HTTP/2 connections from untrusted sources. AppTrana and similar WAFs have published protections targeting the malformed HEADERS+RST_STREAM frame sequences. As a network-layer control, restrict HTTP/2 access to known-good clients where architecturally feasible.

5. Monitor for worker crashes

Keep a watch on Apache error logs for repeated worker restarts and SIGSEGV entries, a reliable early signal of active exploitation:

sudo journalctl -u apache2 -f | grep -i "segfault|child pid|exit signal"
tail -f /var/log/apache2/error.log | grep -E "SIGSEGV|worker|crash"

Indicators of Compromise (IoCs)

No public IoCs (file hashes, known attacker IPs, or network signatures) have been formally published for CVE-2026-23918 as of May 9, 2026. The nature of this exploit, using standard, well-formed TCP/HTTP/2 framing, means network-level signatures are not straightforward. Monitor the Apache security advisory and oss-security mailing list for updated IoC releases.

In the interim, use this behavioural hunting checklist:

On the server:

  • Repeated worker process crashes logged in /var/log/apache2/error.log - look for AH00161: server still has X connections, segfault, or SIGSEGV paired with mod_http2 stack traces
  • Apache worker PID churn: compare expected vs. actual worker spawn rates via server-status
  • Core dumps in the Apache working directory (if core dumps are enabled): ls -lt /var/crash/ /tmp/core*
  • Unexpected drops in request completion rates for HTTP/2 sessions

In traffic logs:

  • High volume of HTTP/2 RST_STREAM frames (stream error code non-zero) from a single source IP or small IP range within a short window
  • HTTP/2 sessions that send exactly one or two frames before closing
  • Unusual amounts of incomplete HTTP/2 transactions in access logs (0-byte or very short responses, connection resets)

Configuration integrity:

  • Verify Protocols directives haven’t been silently modified to re-enable h2 after a workaround was applied
  • Confirm the running Apache binary version: apache2 -v or httpd -v
  • For Docker: verify the image digest matches the expected 2.4.67 tag

Watch the Apache HTTP Server security advisory page and oss-security for updates, especially if RCE exploitation is confirmed in the wild after publication of this post.

References