Critical CVSS 9.8 EPSS 0.2275 🔬 Patch diffed 2026-06 archive

Executive Summary

Integer overflow or wraparound in Windows HTTP.sys allows an unauthorized attacker to execute code over a network.

Overview

9.8
CVSS CRITICAL
Critical
MS Severity
Not Exploited
MS Exploit Status
More Likely
MS Exploit Likelihood
Category Remote Code Execution
Released Jun 9 2026
Last Updated Jun 9 2026
Publicly Disclosed No
CISA KEV Not Listed
Known Exploits None Known
EPSS Score 0.2275 — 0.97522 percentile
NVD CVSS 9.8 CRITICAL — matches MSRC

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C
ATTACK VECTOR
Network
ATTACK COMPLEXITY
Low
PRIVILEGES REQUIRED
None
USER INTERACTION
None
SCOPE
Unchanged
CONFIDENTIALITY
High
INTEGRITY
High
AVAILABILITY
High
EXPLOIT CODE MATURITY
Unproven
REMEDIATION LEVEL
Official Fix
REPORT CONFIDENCE
Confirmed
Temporal Score: 8.5

EPSS Score

0.2275
probability of exploitation in the next 30 days
0.97522 percentile - updated 2026-08-14
View on FIRST.org

Affected Products

30 affected products
Product KB Article Severity Impact Restart Required
Windows 10 Version 1607 for 32-bit Systems 5094122 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 1607 for x64-based Systems 5094122 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 1809 for 32-bit Systems 5094123 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 1809 for x64-based Systems 5094123 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 21H2 for 32-bit Systems 5094127 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 21H2 for ARM64-based Systems 5094127 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 21H2 for x64-based Systems 5094127 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 22H2 for 32-bit Systems 5094127 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 22H2 for ARM64-based Systems 5094127 (Security Update) Critical Remote Code Execution Yes
Windows 10 Version 22H2 for x64-based Systems 5094127 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 23H2 for ARM64-based Systems 5093998 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 23H2 for x64-based Systems 5093998 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 24H2 for ARM64-based Systems 5094126 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 24H2 for x64-based Systems 5094126 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 25H2 for ARM64-based Systems 5094126 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 25H2 for x64-based Systems 5094126 (Security Update) Critical Remote Code Execution Yes
Windows 11 Version 26H1 for ARM64-based Systems 5095051 (Security Update) Critical Remote Code Execution Yes
Windows 11 version 26H1 for x64-based Systems 5095051 (Security Update) Critical Remote Code Execution Yes
Windows Server 2012 5094042 (Monthly Rollup) Critical Remote Code Execution Yes
Windows Server 2012 (Server Core installation) 5094042 (Monthly Rollup) Critical Remote Code Execution Yes
Windows Server 2012 R2 5094041 (Monthly Rollup) Critical Remote Code Execution Yes
Windows Server 2012 R2 (Server Core installation) 5094041 (Monthly Rollup) Critical Remote Code Execution Yes
Windows Server 2016 5094122 (Security Update) Critical Remote Code Execution Yes
Windows Server 2016 (Server Core installation) 5094122 (Security Update) Critical Remote Code Execution Yes
Windows Server 2019 5094123 (Security Update) Critical Remote Code Execution Yes
Windows Server 2019 (Server Core installation) 5094123 (Security Update) Critical Remote Code Execution Yes
Windows Server 2022 5094128 (Security Update) Critical Remote Code Execution Yes
Windows Server 2022 (Server Core installation) 5094128 (Security Update) Critical Remote Code Execution Yes
Windows Server 2025 5094125 (Security Update) Critical Remote Code Execution Yes
Windows Server 2025 (Server Core installation) 5094125 (Security Update) Critical Remote Code Execution Yes

Patches

10 patches
Article Type Restart
5094122 Security Update Yes
5094123 Security Update Yes
5094127 Security Update Yes
5093998 Security Update Yes
5094126 Security Update Yes
5095051 Security Update Yes
5094042 Monthly Rollup Yes
5094041 Monthly Rollup Yes
5094128 Security Update Yes
5094125 Security Update Yes

Patch Diff

ghidriff · http.sys (KB5060842)

Remote, pre-auth kernel pool overflow (CWE-190 -> CWE-122) in HTTP.sys HTTP/1.x header parsing. UlpParseNextRequest tracks receive buffers in a per-request buffer-reference array with 16-bit capacity (+0x640) and count (+0x642) fields. When count reaches capacity it grows the array: ExAllocatePool3(0x28 + capacity*8), memmove(count<<3), then capacity += 5 as a 16-bit add WITH NO OVERFLOW CHECK. After 13,107 growths capacity=0xFFFB; +5 = 0x10000 truncates to 0. The next reference forces a grow that allocates only 0x28+0*8 = 40 bytes but memmoves count<<3 (~524,256 bytes) -> ~500KB NonPagedPool overflow. Reachable only over HTTP/1.x-over-TLS: SChannel delivers each TLS record as a separate buffer (1:1 record->reference), so an attacker sends one header line per TLS record; plaintext HTTP coalesces and cannot climb the count. Needs MaxRequestBytes >= 262144 (non-default). IN-HOUSE ghidriff diff of 10.0.26100.8521 -> .8655 confirms the ZDI/TrendAI root cause exactly and reveals the fix: the growth logic is extracted into a new routine UlpReferenceBuffers that adds new=capacity+5; if (new < capacity) bail - the missing 16-bit overflow check. The fix is GATED behind a Known Issue Rollback global UxKirRefBufferOverflowCheck: when that byte is 0 the patched binary runs the ORIGINAL unchecked growth path, so file version alone does not determine patch state. Credit: MSRC haowei yan, goodbyeselene (@ynwarcs); public analysis Yazhi Wang & Jonathan Lein (TrendAI/ZDI).

Pre-patch version 10.0.26100.8521 Download
Post-patch version 10.0.26100.8655 Download
Function Address Change Note
UlpParseNextRequest pre: inline growth (calls memmove) -> post: calls UlpReferenceBuffers code (vulnerable inline growth removed, replaced by call to fixed routine) Pre-patch inlines the buffer-ref array growth: ExAllocatePool3(0x28 + *(ushort*)(state+0x640)*8), memmove(*(ushort*)(state+0x642) << 3), *(short*)(state+0x640) += 5 with no overflow check. Post-patch the inline block is replaced by cVar4 = UlpReferenceBuffers(state, buffer). Match 80%; loses direct memmove/ExAllocatePool3, gains UlpReferenceBuffers in its called-list.
UlpReferenceBuffers 140097880 (effectively new; ghidriff mis-matched to WPP_SF_qII at 21%) added (extracted, bounds-checked growth routine; KIR-gated) New routine holding the growth logic. Branches on global UxKirRefBufferOverflowCheck: if 0, runs the ORIGINAL vulnerable path (0x28 + capacity*8 alloc, capacity += 5, no check); if non-zero, computes uVar6 = capacity + 5, `if (uVar6 < capacity) goto bail` (16-bit overflow guard), allocates uVar6<<3, memmoves count<<3, stores the checked capacity. Both paths ship in .8655.
View full diff report View RCA report

Attack Path

One HTTP header line per TLS record overflows a 16-bit array-capacity counter, desyncing a 40-byte allocation from a ~500KB memmove in the kernel

Attack path for CVE-2026-47291 One HTTP header line per TLS record overflows a 16-bit array-capacity counter, desyncing a 40-byte allocation from a ~500KB memmove in the kernel 01 — ENTRY Remote unauthenticated attacker opens an HTTPS (TLS) connection to HTTP.sys AV:N, PR:N. HTTP.sys listens on 443 pre-auth. The bug is specific to HTTP/1.x over TLS - HTTP/2 and HTTP/3 use different parser paths that never touch the buffer-reference array. 02 — CONTROLLED INPUT Sends one HTTP/1.x header line per TLS application-data record SChannel decrypts each TLS record independently and delivers it as a separate buffer via UlHttpBufferReceiveEvent, giving a 1:1 record->buffer-reference mapping. ~65,536 tiny records (~262KB) are needed; MaxRequestBytes must be >= 262144 (non-default). 03 — PATH UlpParseNextRequest grows the buffer-reference array by 5 slots each time count reaches capacity capacity (+0x640) and count (+0x642) are 16-bit fields. Growth: ExAllocatePool3(0x28 + capacity*8), memmove(count<<3), capacity += 5. 04 — MISSING CHECK capacity += 5 is a 16-bit add with no overflow check After 13,107 growths capacity = 0xFFFB; the next += 5 gives 0x10000, truncated to 0x0000 in the 16-bit field. count (>= 65,536) now exceeds the zeroed capacity, forcing one more grow. 05 — PRIMITIVE 40-byte allocation vs ~500KB memmove -> kernel NonPagedPool overflow -> RCE/DoS The wrap makes ExAllocatePool3 request 0x28 + 0*8 = 40 bytes while memmove copies count<<3 (~524,256 bytes) into it - a ~500KB kernel heap overflow. Bugcheck (DoS) or, under controlled layout, kernel code execution. The June fix (UlpReferenceBuffers: if (capacity+5 < capacity) bail) is gated behind the KIR toggle UxKirRefBufferOverflowCheck.

Derived from the patch delta: the checks added by the vendor identify which fields crossed a trust boundary unvalidated. Reachability and privilege are taken from the call chain in the RCA report.

Known Exploits

Acknowledgments

Microsoft
haowei yan
goodbyeselene