CVE-2026-48095: One Undefined Shift, 256 MB Into 1 Byte, and the Signature Fallback That Means ‘.rar’ Doesn’t Save You
CVE-2026-48095, tracked by GitHub Security Lab as GHSL-2026-140, is a heap buffer write overflow in 7-Zip’s NTFS archive handler. The fix shipped in 7-Zip 26.01 on April 27, 2026, three days after Jaroslav Lobačevski (@JarLob) reported it via SourceForge. Public disclosure came on May 22, 2026 — twenty-five days after the patch landed. The proof-of-concept (a small Python script named gen_ntfs_sparse.py that emits a malformed NTFS image) is public. CVSS is 8.8 with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, which is the standard “user opens a file, attacker controls heap” shape.
The bug itself is a one-line C++ defect. The reason it matters more than the average 7-Zip CVE is the signature-based fallback logic in the parser. The file extension doesn’t gate the vulnerable handler. A crafted NTFS image renamed to .zip, .rar, .7z, or no extension at all reaches the same code path. Email gateway extension policies, AV file-type filters, and “we don’t allow .iso attachments” rules do not help.
This is a defender-side analysis of a publicly disclosed and patched vulnerability against your own deployed software, for research and patch-prioritization purposes. No exploit walk-through.
What actually happens
The vulnerable function is CInStream::GetCuSize() in NtfsHandler.cpp:687, per GitHub Security Lab’s advisory. The body is one line:
UInt32 GetCuSize() const { return (UInt32)1 << (BlockSizeLog + CompressionUnit); }
BlockSizeLog is read from the NTFS volume header. CompressionUnit is read from the compressed data attribute. A crafted NTFS image can set BlockSizeLog = 28 and CompressionUnit = 4, making the shift exponent 32. C++ undefined behavior territory: shifting by the type’s full bit-width is not portable. On x86/x64 hardware the CPU masks the shift count to 5 bits, so (UInt32)1 << 32 evaluates to 1. Not 256 MB. One.
The downstream allocation is _inBuf.Alloc(cuSize). The downstream write is ReadStream_FALSE() reading attacker-controlled compressed data. The mismatch between what the allocator was told (1 byte) and what gets written (the compressed-unit payload, which the primary GHSL advisory reports as up to 256 MB of attacker data) is the heap overflow. The advisory notes the CInStream vtable pointer sits approximately 304 bytes from the overflow site, which is the classic vtable hijack shape — the operator gets a write-where primitive over adjacent heap objects, and the vtable is sitting right there.
One operational caveat from the GHSL advisory worth pinning: on x64 systems, successful exploitation requires roughly 8 GB or more of RAM, because the corresponding _outBuf allocation is 8 GB. The bug is reachable on smaller systems but produces a crash rather than a corrupt-then-execute path. That’s the only part of this where “favorable conditions” matter — and per SocPrime’s writeup, that’s the framing for why the outcome on RAM-constrained systems lands as denial-of-service rather than RCE. The primary GHSL advisory is the more standardized RCE positioning; the SocPrime caveat is the operational nuance for hardware-constrained environments. Both are worth knowing. Most enterprise workstations in 2026 have 16 GB or more, so the RCE path is the planning case for most defenders.
Why the file extension doesn’t save you
This is the part of the advisory that should drive the patch-urgency conversation. 7-Zip’s parser dispatch logic is two-stage: it first tries handlers that match the file extension, and if those fail, it falls back to signature-based detection across the remaining handlers in priority order. The NTFS handler matches the "NTFS " signature at byte offset 3 inside the file. So a file with a .zip extension that fails ZIP parsing (because the bytes aren’t ZIP), then fails RAR (because the bytes aren’t RAR), then fails 7z, then fails everything else above NTFS in the dispatch order, eventually reaches the NTFS handler — which happily parses the crafted NTFS image and hits the vulnerable shift.
The practical consequence: any extension-based filtering at the email gateway, sandbox, or endpoint is a partial mitigation, not a complete one. The user who clicks an invoice.rar attachment that’s actually a malformed NTFS image gets the same parsing dispatch as if they’d clicked image.ntfs. The signature-routing is by design — 7-Zip prides itself on opening malformed archives that other tools reject — and the design widens the attack surface for any handler-specific bug. NTFS today, SquashFS or UDF tomorrow.
This is also why “we don’t extract .ntfs or .img files” is not a defense. Renaming is free.
The 25-day quiet patch window
The disclosure timeline from the GHSL advisory:
- April 24, 2026 — private report to 7-Zip via SourceForge
- April 27, 2026 — fix released in 7-Zip 26.01 (three calendar days)
- May 22, 2026 — public advisory published (25 days after the fix)
Three days from report to fix is fast even by responsive-maintainer standards. Twenty-five days from patched-release to public disclosure is the operationally interesting number. That’s the window in which the patched binary was sitting on the official 7-Zip download page with no public advisory and no CVE indexed, and the 7-Zip 26.01 changelog (per the official history.txt) says only that “bug fixes were applied” — no CVE, no security note, no urgency signal. Patient defenders running diff-based hunting against open-source projects had 25 days to find this themselves. Patient attackers also had 25 days.
The relevance for the patch decision today: 7-Zip 26.01 has been available since late April, and the silent-fix-then-disclosure pattern means update cadence matters more than usual. Tenants that pull 7-Zip from controlled internal mirrors, package managers with their own release lag, or vendor-bundled distributions of 7-Zip (it ships embedded in a lot of file-management and forensics tools) need to verify the version actually running on endpoints today, not the version the install package thought it was installing six months ago.
The cluster around CVE-2026-48095
CVE-2026-48095 is the headline CVE but it’s not alone. Per GBHackers’s cluster reporting on the same disclosure batch, GHSL-2026-115 through GHSL-2026-122 are a set of medium-severity information-disclosure variants in adjacent 7-Zip handlers, all patched in the same 26.01 release. The cluster spans SquashFS (32-bit integer overflow), UEFI capsule (.scap) handling, UDF, and WIM. GBHackers’s writeup notes the UEFI capsule parser could leak up to 1 GiB of uninitialized heap memory in the affected configuration — striking enough to flag the attribution: that figure is from GBHackers’s cluster-level summary; I have not seen the underlying GHSL-2026-XXX advisories for the individual cluster entries directly.
The cluster also reportedly contains bugs that have been present since the 9.x series. That’s a 7-Zip release line stretching back roughly fifteen years. The implication is that this batch is a coordinated cleanup of an old archive-handler attack surface, not a single one-off, and the 26.01 release is more security-relevant than the changelog phrasing suggests.
Operationally, the cluster matters because the same signature-fallback logic that makes the NTFS bug reachable from any extension also makes the SquashFS, UDF, and WIM bugs reachable the same way. The patch covers all of them. The patch-priority calculation is “update to 26.01” rather than “decide which of these to apply first.”
Detection and mitigations
Update to 7-Zip 26.01. That’s the only complete mitigation. Everything below is partial.
Patch-tracking specifics worth wiring up if you haven’t:
Inventory the actual 7-Zip versions running, not the versions the package thinks it deployed. 7-Zip ships embedded in a meaningful number of other tools: file-management utilities, forensics suites, malware-analysis sandboxes, IDE extensions, backup software, even some print drivers. Those bundled copies don’t update when the user runs 7z u or applies the package manager update. Inventory needs to find every 7z.exe, 7za.exe, 7zFM.exe, and the 7zxa.dll / 7z.dll distribution. The version string in the binary is the truth; the registry entry might not be.
File parsing hygiene at the gateway. Mail and web gateways that route attachments through 7-Zip-based sandboxing or unpacking are the high-yield targets. If your sandbox uses 7-Zip pre-26.01 for archive expansion, the sandbox itself is exposed to the vulnerable code path on every malformed-archive sample it processes. That’s a high-volume, high-trust execution context. Update the sandbox before the workstations if you can only do one first.
Heuristic detection on the parsing failure pattern. Per SocPrime’s threat-intel writeup, behavioral indicators worth hunting on include “crashes involving 7-Zip around NTFS-like content” and “suspicious archive-opening activity.” For Defender or equivalent EDR, the heuristic is a 7zFM.exe or 7z.exe process exit with a crash status that correlates with a recently-opened file matching an archive extension but not the expected magic bytes. The signal is noisy (legitimately malformed archives crash 7-Zip occasionally) but the cluster of crash-after-extension-mismatch on previously-clean hosts is worth alerting on at low priority.
Hunt on the file pattern, not just the extension. YARA rules looking for the "NTFS " signature at byte offset 3 in files with non-.ntfs/.img extensions are a low-cost way to catch the obvious case of signature-mismatch routing. The advisory doesn’t publish a vendor rule; the indicator is simple enough to build internally.
Treat the PoC as available. gen_ntfs_sparse.py is public. The skill required to weaponize the PoC into a delivered payload is well-trodden territory for any operator working in 2026. Assume the gap between PoC availability and observed in-the-wild use is short, even though no public reports of exploitation exist as of this writing. The operational planning case is “exploit attempts incoming,” not “we have time.”
Permissions hardening for the 7-Zip process. This is the long-term mitigation that survives the next 7-Zip handler bug, because there will be a next one. 7-Zip running in user context with the user’s full token is the default. 7-Zip running in a sandboxed AppContainer or under a restricted token reduces the post-exploit blast radius regardless of which handler bug is being exploited next quarter. The same logic applies to any other archive utility (WinRAR, peazip) — the archive-parser attack surface is broad enough that defense-in-depth at the process layer is a structural investment, not a per-CVE response.
Where this lands
The patch is easy. The deployment is the work.
7-Zip 26.01 has been available since April 27. The CVE has been indexed since May 22. The PoC has been public since the advisory. The interesting question is not “should we patch” but “do we actually know what version of 7-Zip is running on every endpoint, every server, every embedded copy inside every other tool we deploy.” For most shops the honest answer is no, and the next ninety minutes of inventory work pays back the next quarter’s worth of incident response.
The structural lesson — the signature-based fallback parsing meaning that file-extension filtering is incomplete — generalizes past this CVE. Archive utilities trade restrictive parsing for broad compatibility, and the broad-compatibility dispatch logic is the part that converts a single-handler bug into a multi-extension attack surface. Until that design pattern changes industry-wide (it won’t), the patch-cadence-and-process-isolation posture is the durable answer.
The undefined-behavior shift in GetCuSize() is the easy part to fix. The fact that handler-cluster CVEs in archive utilities will keep happening is the part that needs structural defense.