CVE-2026-88052 in Tesseract
Summary
by MITRE • 09/10/2026
Tesseract is an open source OCR engine. In version 5.5.3 and earlier, UNICHARSET::load_via_fgets in src/ccutil/unicharset.cpp trusts the declared unichar count as a loop bound and uses id as an unchecked index into the unichars vector. unichar_insert_backwards_compatible can leave the vector unchanged for an empty, duplicate, or already-encodable representation, causing id to become larger than unichars.size(). Subsequent set_* calls and the write to unichars[id].properties.enabled then write UNICHAR_PROPERTIES beyond the vector during initialization in both the default LSTM and legacy engines, causing heap corruption, a crash, or potentially controlled corruption. No fixed release is available as of this review.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 09/10/2026
The vulnerability identified in Tesseract versions 5.5.3 and earlier represents a critical memory safety flaw within the core character set initialization logic, specifically located in the UNICHARSET::load_via_fgets function found in src/ccutil/unicharset.cpp. This component is responsible for parsing and loading unicharsets, which are fundamental data structures defining the characters recognized by the optical character recognition engine. The root cause of this vulnerability lies in a failure to validate input data against internal state constraints before performing array operations. Specifically, the code trusts the declared unichar count provided during file load as a valid loop bound without verifying that the resulting identifiers correspond to actual allocated memory slots within the unichars vector. This lack of bounds checking creates a direct pathway for out-of-bounds access when processing malformed or maliciously crafted input files.
The technical mechanism triggering this flaw involves a specific edge case in the unichar_insert_backwards_compatible function, which manages the insertion and deduplication of character identifiers within the internal data structures. When this function encounters an empty string, a duplicate identifier, or a representation that is already encodable by existing entries, it intentionally leaves the underlying vector unchanged to maintain consistency and avoid redundancy. However, the calling logic in load_via_fgets does not account for this potential lack of insertion. Consequently, the variable id, which tracks the index assigned during processing, can end up being larger than the actual size of the unichars vector after such a non-insertion event occurs. This discrepancy creates an invalid memory offset that is subsequently used to access and modify object properties.
The operational impact of this vulnerability is severe, primarily manifesting as heap corruption due to out-of-bounds writes during the initialization phase of both the default LSTM engine and the legacy Tesseract engines. The code proceeds to execute set_* calls on objects indexed by the invalid id value, culminating in a direct write operation to unichars[id].properties.enabled. Because this index exceeds the allocated bounds of the vector, the write corrupts adjacent memory regions on the heap. This corruption can lead to immediate application crashes, resulting in denial-of-service conditions for systems relying on Tesseract for text extraction. More critically, because the vulnerability allows controlled writes beyond array boundaries during initialization, it presents a potential avenue for arbitrary code execution if an attacker can precisely manipulate the corrupted memory layout and control data values written into adjacent structures.
From a classification perspective, this flaw aligns with CWE-125 Out-of-bounds Read and CWE-787 Out-of-bounds Write, as the application accesses memory outside of its intended bounds due to insufficient validation of input-driven indices. The attack vector is typically classified under ATT&CK technique T1059 Command and Scripting Interpreter if leveraged via scriptable interfaces or more broadly within initial access vectors where malicious OCR inputs are processed by a service. The vulnerability highlights the risks associated with trusting external data formats without rigorous structural validation, particularly in legacy codebases that may rely on implicit assumptions about input integrity rather than explicit bounds checking.
Mitigation strategies for this issue must focus on implementing strict input validation and defensive programming practices within the unicharset loading routines. Developers should ensure that any index derived from parsed file contents is validated against the current size of the target vector before any access or modification occurs. In cases where insertion does not occur due to duplicates or empty entries, the logic must be adjusted to either skip subsequent operations on those identifiers or update the tracking variables to reflect the actual state of the container. Until a fixed release is available, organizations should consider implementing input sanitization at the ingestion layer to reject unicharset files that exhibit signs of malformed structure or excessive identifier counts relative to expected character sets. Additionally, enabling AddressSanitizer during testing phases can help detect such memory safety violations early in the development lifecycle before deployment into production environments where they could be exploited by adversaries providing crafted OCR inputs.