Cloudanix VulnDB

CVE-2026-88054

Medium · 5.5

CVSS

5.5

EPSS

0.2%

Published

Sep 10, 2026

CISA due date

—

Cloudanix analysis

Monitor only SSVC: Track

A bad OCR model file can crash software that reads text from images, and there is no official fix yet.

Exploit Available
Exploitation
Other
Attacker needs
Local User
Complexity
Low
Impact
Denial Of Service
Component
Library
Class
Denial of service
Remediation
No Fix Yet
Effort
Other
Patch risk
Low

What it actually does

In Tesseract 5.5.3 and earlier, a crafted .traineddata model can pass Plumbing::DeSerialize with a zero-length stack for NT_SERIES, NT_PARALLEL, or NT_REVERSED layers. LSTMRecognizer initialization then calls CacheXScaleFactor, which indexes stack_[0] on an empty vector and dispatches a virtual call through an invalid Network pointer, causing a deterministic crash and process-level denial of service at model load. Confidentiality and integrity are not affected.

Why it matters to the business

OCR and document-processing services that load untrusted or user-supplied models can be taken offline by a single malicious .traineddata file. There is no official fixed release, public exploit code is available, and the issue has been known for about 27 days. The flaw is availability-only (CVSS 5.5), is not in CISA KEV, and is not tied to ransomware. Unpatched embeddings of Tesseract in IDP, scanning, or automation pipelines risk outages and SLA impact until model loading is restricted or the engine is isolated.

How an attack unfolds

An attacker places a malicious .traineddata file where a vulnerable Tesseract-based application will load it (local path, upload, packaged language data, or adjacent model directory). The file is accepted because deserialization allows an empty stack for series, parallel, or reversed LSTM layers. On LSTMRecognizer init the engine follows that empty stack and crashes. The attacker needs only that the victim load the model; no extra privileges or interactive UI are required. The result is a reliable crash of the OCR process, not code execution.

How to fix it

No vendor-fixed version is published. Do not load untrusted .traineddata files; allowlist known-good model hashes and block user-supplied or internet-fetched models. Run Tesseract in a short-lived, tightly sandboxed worker so a crash does not take down the parent service. Pin and inventory libtesseract/tesseract packages at known versions and monitor upstream for a patch that rejects zero-length stacks in Plumbing::DeSerialize and Series::CacheXScaleFactor. Where possible, isolate model load behind a process boundary with restart limits.

How to confirm the fix worked

Inventory hosts and containers for tesseract/libtesseract 5.5.3 and earlier. Confirm production only loads hashed, internally approved .traineddata files. After applying an upstream fix or a local guard that rejects empty NT_SERIES/NT_PARALLEL/NT_REVERSED stacks, load representative models in a non-production worker and verify initialization completes without a crash. Treat any remaining crash on model load as unpatched exposure.

Typical attack path

  1. Obtain access to a path or upload that a Tesseract 5.5.3-or-earlier application will use as a .traineddata model
  2. Supply a model whose serialized LSTM graph includes an NT_SERIES, NT_PARALLEL, or NT_REVERSED layer with a zero-length stack
  3. Cause or wait for LSTMRecognizer initialization (normal model load)
  4. The process aborts on an invalid Network pointer dereference, denying OCR service

How to detect it

Hunt for process crashes at Tesseract model load rather than during image recognition. Review application, container, and systemd/journal logs around LSTMRecognizer or traineddata initialization; collect coredumps and stack traces that mention Series::CacheXScaleFactor, Plumbing::DeSerialize, or an invalid Network pointer. Correlate crashes with recent writes or uploads of .traineddata files, unexpected model paths, and worker restart storms. This CVE is not associated with named threat actors or ransomware; treat clusters of identical load-time crashes plus a new model file as likely abuse.

  • Series::CacheXScaleFactor
  • LSTMRecognizer
  • Plumbing::DeSerialize
  • stack_[0]
  • NT_SERIES
  • NT_PARALLEL
  • NT_REVERSED
  • .traineddata
  • tesseract
  • libtesseract
  • src/lstm/series.cpp
  • src/lstm/plumbing.cpp
  • src/lstm/lstmrecognizer.cpp

What your security team should do

  • Immediately stop loading untrusted or user-uploaded .traineddata models in production OCR paths
  • Isolate Tesseract model load in a sandboxed, restart-limited worker so a crash is contained
  • Inventory all tesseract/libtesseract 5.5.3-and-earlier deployments and track upstream for a fixed release
  • Allowlist model files by cryptographic hash and alert on new or modified .traineddata artifacts
  • Prioritize patching when a fix ships; exploit code is already available and there is no KEV due date to wait on

The record

Tesseract is an open source OCR engine. In version 5.5.3 and earlier, Plumbing::DeSerialize in src/lstm/plumbing.cpp rejects excessively large network stacks but accepts a zero-length stack for NT_SERIES, NT_PARALLEL, or NT_REVERSED layers in a crafted .traineddata model. During LSTMRecognizer initialization in src/lstm/lstmrecognizer.cpp, CacheXScaleFactor(XScaleFactor()) reaches Series::CacheXScaleFactor in src/lstm/series.cpp, which dereferences stack_[0] on the empty vector and invokes a virtual method through an invalid Network pointer. This causes a deterministic crash and denial of service at model load. No fixed release is available as of this review.

Affected packages

Ecosystem Package Introduced Fixed

Related vulnerabilities