NULL pointer dereference in the Zephyr HTTP/2 server when a header block is completed by a CONTINUATION frame
Affects Zephyr 4.1.0 up to 4.3.2 and 4.4.0 up to 4.5.0 when the HTTP/2 server accepts cleartext h2c. Fixed in 4.3.2 and 4.5.0.
Written by anthropic/claude-haiku-5.5 from the sources below. Verify against them.
- Exploited
- No known exploitation
- Fix
- Fixed in 4.3.2, 4.5.0
- Who is exposed
- Not reported
Do first: Upgrade to a fixed version: 4.3.2, 4.5.0.
- Last modified
- A 0-100 score for how much a CVE matters across the industry: exploitation, exposure, how widely the software is used, severity and whether a fix exists.What do these mean? →
- 25/100 · provisional
- How many real-world setups can hit the bug, from the vendor's advisory and CISA data. It does not know your setup.What do these mean? →
- Unclear
- Whether working attack code is public (Exploit-DB, Metasploit, Nuclei or GitHub). Public code makes attacks easier.What do these mean? →
- None on Exploit-DB, Metasploit or GitHub
Summary
The HTTP/2 server in Zephyr has a NULL pointer dereference that a remote attacker can trigger over the network without logging in, by sending a CONTINUATION frame that no HEADERS frame opened or a split header block. Successful exploitation crashes the device, causing a denial of service.
Read the original description
The HTTP/2 server in subsys/net/lib/http/http_server_http2.c clears the connection's stream binding at the start of every frame. handle_http_frame_header() executed client->current_stream = NULL unconditionally, but a CONTINUATION frame does not open a new stream and enter_http_frame_continuation_state() never re-bound one, so the rest of the header block was processed with client->current_stream unset. Two paths then write through the NULL pointer. A request for an unregistered resource, or a method the matched resource does not support, is answered by send_http2_404() or send_http2_405(), and both call send_headers_frame(), which unconditionally sets client->current_stream->headers_sent = true. A POST, PUT or PATCH to a registered dynamic resource reaches handle_http2_dynamic_resource(), which unlike its siblings (handle_http2_static_resource(), dynamic_get_del_opts_req_v2(), dynamic_post_put_req_v2()) had no client->current_stream == NULL guard, and stores through the pointer with client->current_stream->current_detail = dynamic_detail.
Any peer that can reach the server can trigger this without authentication or prior state. A single stray CONTINUATION frame with END_HEADERS set, sent right after the client preface and requesting any unregistered path, is enough, because nothing rejected a CONTINUATION that no HEADERS frame had opened. A legitimate split header block (a HEADERS frame with END_HEADERS clear whose payload ends on a header-field boundary, then a CONTINUATION with END_HEADERS set) reaches the same state. The in-tree test test_http2_post_headers_with_continuation() did not catch this because it splits the header block mid field, which takes the handle_incomplete_http_header() shortcut that keeps the stream bound.
The result is a write to a fixed low address (a small offset into struct http2_stream_ctx), which faults on mainstream targets (flash/vector-table region on Cortex-M, or a trap under MPU/MMU null-pointer detection), and the default fatal-error handler halts the system. Impact is an unauthenticated, remotely triggerable denial of service against any device running the HTTP/2 server: the 404 path needs no particular resource to be registered, and HTTP/2 is built into CONFIG_HTTP_SERVER with cleartext h2c accepted, so TLS does not prevent it. Neither the target address nor the written value is attacker-controlled, so there is no confidentiality or integrity impact. Applications built without CONFIG_HTTP_SERVER are not affected.
cve.now Index
- Exploitation?/40Unknown. No CISA SSVC exploitation rating yet
- Exposure17/25No login or user action needed, reachable over the network without a login · Unknown: Advisories don't say whether default setups are affected
- Reach?/20Unknown. No tracked technology or package matched
- Severity7.5/10CVSS 7.5
- No patch0/5No signal
What would change the score
- Would score about 70 if added to CISA KEV
- Would score about 65 if CISA's SSVC rates exploitation active
- Would score about 30 if advisories confirm default setups are exposed
What to do
Upgrade to a fixed version: 4.3.2, 4.5.0.
Timeline
- CVE published
- First seen by cve.now
Affected versions
- zephyr
From 4.1.0 · fixed in 4.3.2; From 4.4.0 · fixed in 4.5.0
Evidence 2
- Advisory
- Patch
Corrections
None so far.
Something wrong on this page? Report an error. Every fix is listed here.
Questions about CVE-2026-87045
Is CVE-2026-87045 being exploited?
It is not in CISA's Known Exploited Vulnerabilities catalog, and CISA's SSVC assessment does not mark exploitation as active. That does not mean it has not been attacked: vendors and researchers can report attacks before CISA lists them. No public exploit code is tracked.Source: cve.now feed data
What does this mean?
The HTTP/2 server dereferences a NULL pointer when a header block is completed by a CONTINUATION frame. The resulting fault makes the default fatal-error handler halt the system, which is a denial of service.Source: github.com
Which versions are affected by CVE-2026-87045?
zephyr: from 4.1.0 before 4.3.2; from 4.4.0 before 4.5.0.Source: cve.now feed data
Am I affected, and how do I check?
Zephyr 4.1.0 up to 4.3.2 (exclusive) and 4.4.0 up to 4.5.0 (exclusive), where HTTP/2 is built into CONFIG_HTTP_SERVER with cleartext h2c accepted. Check the Zephyr version in use and whether CONFIG_HTTP_SERVER with h2c is enabled in the build configuration.Source: github.com
How do I fix CVE-2026-87045?
Upgrade to Zephyr 4.3.2 on the 4.3 line or 4.5.0 on the 4.5 line.Source: github.com