What this actually is.
Technical background, root cause, and affected surface.
An out-of-bounds heap write exists in the RAR5 recovery-volume (.rev) parser in WinRAR and UnRAR (RecVolumes5::ReadHeader in recvol5.cpp). The RecItems vector is sized only when the first .rev file in a set is processed; subsequent .rev files supply an independent RecNum value that is validated against that file's own TotalCount field but never against the actual size of RecItems. A crafted set of two or more .rev files can therefore write an attacker-controlled 32-bit value (the header's RevCRC field) to RecItems[RecNum] at an attacker-controlled offset up to 65534 * sizeof(RecVolItem) bytes past the allocation, corrupting adjacent heap objects. Triggering requires the victim to run a recovery/test operation on an attacker-supplied .rev set (for example 'unrar t x.part1.rev', WinRAR 'Repair archive', or auto-recovery when extracting a volume set with a missing .rar part). This is the RAR5-path sibling of CVE-2023-40477 (which was fixed in the RAR3 path only in WinRAR 6.23). Fixed in WinRAR / RAR 7.23.
- Vendor
- RARLAB
- Product
- WinRAR / RAR / UnRAR / UnRAR.dll
- Severity
- High
- CVSS Score
- 7.8
- CWE
- CWE-787, CWE-129
- Status
- Patched
- Vector
- CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
From one request
to root shell.
Reproduced in a sandboxed environment. Requires only LAN or WiFi adjacency.
Prerequisite: the victim runs a test/recover operation over an attacker-supplied .rev set - "unrar t x.part1.rev", the WinRAR GUI "Repair archive" action, or automatic recovery when extracting a volume set with a missing .rar part. NextVolumeName walks poc.part1.rev -> poc.part2.rev automatically under RAR5 numbering, so a single "unrar t poc.part1.rev" processes both files.
Constraint: the PoC uses RecNum = 65534, which places the write megabytes past the 2-element allocation and onto an unmapped page, producing a deterministic crash. It does not attempt heap grooming, and no code-execution chain was built.
The bug, and the fix.
File: unrar/recvol5.cpp Affected function: RecVolumes5::ReadHeader(File *RecFile, bool FirstRev) Missing bound: recvol5.cpp:467 - Out-of-bounds write: recvol5.cpp:486 Source audited: UnRAR 7.21 (line numbers below are from that tree). Installed WinRAR/UnRAR 7.22 x64 confirmed affected empirically.
Captured verbatim from disclosure/evidence/02_source_recvol5_readheader.txt (recvol5.cpp lines 439-489, debug markers = 0):
439 uint RecVolumes5::ReadHeader(File *RecFile,bool FirstRev) 440 { ... 461 if (Raw.Get1()!=1) // Version check. 462 return 0; 463 DataCount=Raw.Get2(); 464 RecCount=Raw.Get2(); 465 TotalCount=DataCount+RecCount; 466 uint RecNum=Raw.Get2(); // Number of recovery volume. 467 if (RecNum>=TotalCount || TotalCount>MaxVolumes) // <-- checked against THIS file's TotalCount only 468 return 0; 469 uint RevCRC=Raw.Get4(); // CRC of current REV volume. 470 471 if (FirstRev) 472 { 473 // If we have read the first valid REV file, init data structures 474 // using information from REV header. 475 size_t CurSize=RecItems.size(); 476 RecItems.resize(TotalCount); // <-- sized ONLY for the first .rev file 479 for (uint I=0;I<DataCount;I++) 480 { 481 RecItems[I].FileSize=Raw.Get8(); 482 RecItems[I].CRC=Raw.Get4(); 483 } 484 } 485 486 RecItems[RecNum].CRC=RevCRC; // Assign it here, after allocating RecItems. 487 488 return RecNum; 489 }
Root cause: RecNum is validated at line 467 only against the TotalCount field carried by the same .rev file, and never against RecItems.size(). RecItems is resized at line 476 only while FirstRev is true - that is, from the first .rev file in the set. A later file in the set supplies an independent, larger TotalCount/RecNum pair, so the two values diverge and line 486 writes an attacker-controlled 32-bit value (the header's RevCRC field) at an attacker-controlled index past the end of the allocation.
Prior art: the official RARLAB source diff unrarsrc-6.2.8 (WinRAR 6.22) -> unrarsrc-6.2.9 (WinRAR 6.23), captured in disclosure/evidence/03_official_diff_cve-2023-40477.txt, shows recvol5.cpp IDENTICAL across the CVE-2023-40477 fix, while recvol3.cpp received the added bounds check (if (SrcPos<0 || SrcPos>=ASIZE(SrcFile)) continue; plus P[i]<=0 guards). The 2023 fix therefore hardened only the RAR3 recovery path; the RAR5 path shown above was never bounded until WinRAR/RAR 7.23.
What an attacker does to you.
Post-exploitation outcomes mapped to CVSS impact metrics.
Demonstrated: a controlled out-of-bounds heap write. The written value is the attacker-supplied RevCRC field and the offset is RecNum * sizeof(RecVolItem), reaching up to 65534 * sizeof(RecVolItem) bytes past the allocation. With the PoC's RecNum = 65534 the write lands on an unmapped page and terminates the process - confirmed on the installed release binary (UnRAR 7.22 x64, EXIT_CODE=139 / SIGSEGV, evidence/05) and root-caused with AddressSanitizer as a WRITE access-violation inside RecVolumes5::ReadHeader on pristine 7.21 source (EXIT_CODE=99, evidence/07). The reachable outcome proven by this evidence is denial of service against any process that tests or repairs an attacker-supplied .rev set, including UnRAR.dll consumers that expose recovery-volume handling.
Not demonstrated - assessment only: with a small RecNum the write would land in the near-heap and corrupt adjacent heap objects or allocator metadata rather than hitting an unmapped page. That is the path an attacker would pursue toward control-flow hijack (heap grooming, overwriting a pointer or vtable, then defeating Windows ASLR/DEP/CFG). No code-execution chain was built and none is claimed. The CVSS:3.1 vector recorded for this entry (AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H, 7.8) is a reporter estimate mirroring CVE-2023-40477, the RAR3-path sibling, which ZDI/NVD rated 7.8. It is not a vendor-assigned score.
Exposure: the trigger requires user interaction - the victim must run a test, repair, or auto-recovery operation over the attacker's .rev set - so this is local/user-assisted rather than remotely reachable on its own.
Fix it. In this order.
A runbook, not a checklist. Sequence matters — assume compromise before you act.
Upgrade. Fixed by RARLAB in WinRAR / RAR 7.23, released 2026-06-30, which ships the .rev processing fix. This covers WinRAR.exe, Rar.exe, UnRAR and UnRAR.dll. Products that bundle UnRAR.dll must ship the 7.23 library, not merely update the host application.
Source-level fix for downstream forks and embedders that cannot take 7.23 directly - add the missing bound at recvol5.cpp:467 so RecNum is validated against the actual container size, not only the per-file TotalCount:
if (RecNum>=TotalCount || TotalCount>MaxVolumes || RecNum>=RecItems.size())
return 0;
Optionally also reject .rev files whose DataCount / RecCount / TotalCount differ from the first volume in the set, which removes the header-disagreement primitive entirely rather than only bounding its effect.
Interim mitigation where 7.23 cannot be deployed immediately - the defect is only reachable through recovery-volume processing, so:
Do not run test, repair, or recovery operations over .rev files from untrusted sources.
Be aware that extraction of a volume set with a missing .rar part can invoke recovery automatically, so the trigger is not limited to an explicit "Repair archive" action.
In automated pipelines, filter .rev members out of untrusted uploads before handing archives to UnRAR or UnRAR.dll.
Note for triage: applying the CVE-2023-40477 fix does not address this issue. The official RARLAB 6.22 -> 6.23 diff (evidence/03) shows that fix touched recvol3.cpp only and left recvol5.cpp byte-identical, so RAR5 recovery volumes remained unbounded on every release up to 7.22.
disclose@securin.ioVendors moved in days.
Attackers in hours.
Reconstructed from vendor advisories, CISA bulletins, and Securin research records.
Crafted two-file .rev set generated and verified
generator CRC-32 self-test matches the canonical vector CRC32("123456789") = 0xCBF43926 (evidence/06_crc32_selftest.txt)
Out-of-bounds write confirmed against the installed release binary UnRAR 7.22 x64 with no instrumentation - EXIT_CODE=139, SIGSEGV (evidence/05_installed_unrar_crash.txt)
Root-caused under AddressSanitizer on a pristine UnRAR 7.21 build with no source edits - WRITE access-violation in RecVolumes5::ReadHeader, reached via RecVolumes5::Test (recvol5.cpp:510) and CmdExtract::ExtractArchive (extract.cpp:191), EXIT_CODE=99 (evidence/07_asan_crash.txt)
Confirmed as the unpatched RAR5 variant of CVE-2023-40477 - official RARLAB unrarsrc 6.2.8 to 6.2.9 diff shows recvol5.cpp unchanged while recvol3.cpp received the bounds fix (evidence/03_official_diff_cve-2023-40477.txt)
Reported to RARLAB (Eugene Roshal) by Securin
vendor confirmed the findings the same day
WinRAR / RAR 7.23 released by RARLAB with the .rev processing fix
CVE-2026-14191 assigned by Securin CNA
Securin Zero-Day advisory published
Disclosed 27 days after discovery
Cite, verify, go deeper.
Primary sources — NVD, CISA KEV, and machine-readable IoC feed.