Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-45785

CVE-2026-45785: OpenMcdf DOS Vulnerability

CVE-2026-45785 is a denial of service flaw in OpenMcdf that allows crafted CFB files with cyclic sibling links to trigger infinite loops. This post covers the technical details, affected versions, and mitigation.

Published:

CVE-2026-45785 Overview

CVE-2026-45785 is an infinite loop vulnerability [CWE-835] in OpenMcdf, a .NET/C# library for manipulating Compound File Binary (CFB) files, also known as Structured Storage. Versions 3.1.3 and earlier fail to detect cycles in the directory Binary Search Tree (BST) traversal logic. A crafted CFB file with cyclic Left/Right sibling links causes the TryGetDirectoryEntry loop to run forever, producing an unrecoverable denial of service in any application that parses untrusted CFB input. The issue is fixed in version 3.1.4.

Critical Impact

Applications using OpenMcdf to open untrusted CFB files can be forced into an infinite loop, exhausting CPU resources and causing denial of service.

Affected Products

  • OpenMcdf versions 3.1.3 and earlier
  • .NET/C# applications parsing Compound File Binary Format files with OpenMcdf
  • Downstream tooling consuming CFB, CFS, or MSG files through OpenMcdf APIs

Discovery Timeline

  • 2026-07-17 - CVE-2026-45785 published to NVD
  • 2026-07-23 - Last updated in NVD database

Technical Details for CVE-2026-45785

Vulnerability Analysis

OpenMcdf represents each storage's directory entries as a red-black BST. The name-lookup routine DirectoryTree.TryGetDirectoryEntry (OpenMcdf/DirectoryTree.cs:35-46) walks the tree by repeatedly calling directories.TryGetSibling(child, siblingType, validateColor) inside a while (child is not null) loop.

The per-step validation in TryGetSibling (DirectoryEntries.cs:84-85) only checks that the sibling's name preserves BST ordering relative to the current node. It does not track visited nodes. An attacker who constructs a CFB file whose sibling pointers form a cycle while still satisfying the local ordering comparison can make the loop iterate indefinitely.

The defect is reachable from public API entry points including RootStorage.OpenStorage(name), TryOpenStorage(name), OpenStream(name), and TryOpenStream(name). Any process opening a malicious file hangs on a single CPU core with no recovery path.

Root Cause

The root cause is missing cycle detection during BST traversal. The local-only ordering check is insufficient to guarantee termination when input is attacker-controlled. Because OpenMcdf trusts the on-disk structure to be a well-formed tree, cyclic Left/Right pointers bypass all termination conditions.

Attack Vector

Exploitation requires the victim application to open a crafted CFB file. The attack vector is local (AV:L) and does not require privileges or user interaction beyond opening the file. The impact is limited to availability (A:H) with no confidentiality or integrity effect.

text
// Source: https://github.com/openmcdf/openmcdf/commit/c6f82db722bd85db7b0caed3ca1aa374f1e07bc7
// Patch in OpenMcdf/DirectoryEntries.cs - Enforce binary search tree validation

-    public DirectoryEntry? TryGetSibling(DirectoryEntry entry, SiblingType siblingType, bool validateColor)
+    public DirectoryEntry? TryGetSibling(DirectoryEntry entry, SiblingType siblingType, IDirectoryTreeValidator validator)
     {
-        uint siblingId = siblingType == SiblingType.Left ? entry.LeftSiblingId : entry.RightSiblingId;
+        uint siblingId = entry.GetSiblingId(siblingType);
         if (!TryGetDictionaryEntry(siblingId, out DirectoryEntry? sibling))
             return null;

-        int compare = DirectoryEntryComparer.Compare(sibling.NameCharSpan, entry.NameCharSpan);
-        if ((siblingType is SiblingType.Left && compare >= 0) || (siblingType is SiblingType.Right && compare <= 0))
-            throw new FileFormatException("Directory tree is not sorted.");
-        if (validateColor && entry.Color is NodeColor.Red && sibling.Color is NodeColor.Red)
-            throw new FileFormatException("Red-black tree red-violation.");
+        validator.Validate(entry, sibling, siblingType);
+        return sibling;
+    }

The fix introduces an IDirectoryTreeValidator abstraction that performs structural validation across the traversal, rather than relying on isolated per-step comparisons that cannot detect cycles.

Detection Methods for CVE-2026-45785

Indicators of Compromise

  • A .NET process consuming OpenMcdf that pins a CPU core at 100% shortly after opening a CFB, CFS, or MSG file.
  • User-supplied .cfb, .cfs, .doc, .xls, .ppt, or .msg files that never finish parsing and cannot be canceled.
  • Managed thread stacks showing repeated frames in DirectoryTree.TryGetDirectoryEntry and DirectoryEntries.TryGetSibling.

Detection Strategies

  • Inventory .NET applications and NuGet dependencies to identify use of OpenMcdf at versions <= 3.1.3.
  • Enable application-level watchdogs that time out CFB parsing operations and log the offending file hash.
  • Perform static or SCA scans against project files for the vulnerable OpenMcdf package reference.

Monitoring Recommendations

  • Alert on sustained single-core CPU saturation in services that process user-uploaded Office or CFB documents.
  • Track process runtime for file-parsing worker pods or sandbox jobs and flag jobs exceeding expected duration.
  • Capture and hash rejected or timed-out input files for offline analysis and correlation.

How to Mitigate CVE-2026-45785

Immediate Actions Required

  • Upgrade OpenMcdf to version 3.1.4 or later in all applications, build pipelines, and container images.
  • Rebuild and redeploy any packaged software that statically references the vulnerable library.
  • Enforce parsing timeouts and cancellation tokens around every OpenMcdf API call handling untrusted input.

Patch Information

The fix is available in OpenMcdf release v3.1.4 and described in GitHub Security Advisory GHSA-5qwm-7pvp-w988. The corrective code is in commit c6f82db, which replaces the local ordering check with a full IDirectoryTreeValidator that rejects malformed directory structures.

Workarounds

  • Run CFB parsing in an isolated worker process with a hard wall-clock timeout and CPU quota.
  • Reject files from untrusted sources at the perimeter until the OpenMcdf upgrade is deployed.
  • Constrain OpenMcdf callers with CancellationToken where supported and terminate hung workers automatically.
bash
# Upgrade OpenMcdf via .NET CLI
dotnet add package OpenMcdf --version 3.1.4

# Verify no vulnerable version remains in the dependency tree
dotnet list package --include-transitive | grep -i openmcdf

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.