CVE-2026-59156
Executive Summary
CVE-2026-59156 is an uncontrolled recursion (stack-exhaustion) vulnerability in OpenImageIO, a widely used image I/O toolset embedded in VFX, animation, and rendering pipelines. Prior to versions 3.0.20.0, 3.1.15.0, and 3.2.0.3-beta1, a crafted FITS stream composed of consecutive 2880-byte header blocks lacking the mandatory END keyword drives FitsInput::read_fits_header() (src/fits.imageio/fitsinput.cpp) into unbounded self-recursion, exhausting the application stack and crashing the process.
The impact is a denial-of-service condition (CVSS 3.1 base 6.5, C:N/I:N/A:H) that requires no privileges but does require user interaction — typically a victim opening or processing a maliciously crafted FITS file. Because OpenImageIO is a library consumed by render farms, DCC tools, and asset-processing services, a single malformed asset can terminate a worker process or a multi-tenant conversion service.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Vulnerability Class
CWE-674: Uncontrolled Recursion. The parser follows a recursive-descent design where header parsing re-enters itself on each additional header block, with no depth counter, iteration limit, or termination guard.
Mechanism
The FITS format structures image metadata as a sequence of 2880-byte header blocks. Each block is expected to eventually be terminated by the mandatory END keyword. The vulnerable logic in FitsInput::read_fits_header() re-invokes itself when additional header blocks are present. If an attacker supplies a stream of consecutive 2880-byte blocks that never contains the terminating END keyword, the recursion never reaches a base case.
Each nested call consumes a stack frame. Since there is no bound on recursion depth, the call stack grows until the process's stack limit is reached, producing a stack-overflow condition. In native C++ code this surfaces as an unrecoverable crash (segmentation fault / stack guard page hit) rather than a catchable exception — the standard denial-of-service outcome for unbounded recursion.
Attack Surface
- Input vector: FITS (Flexible Image Transport System) image files/streams processed by OpenImageIO.
- Affected component:
src/fits.imageio/fitsinput.cpp—FitsInput::read_fits_header(). - Trigger primitive: Consecutive 2880-byte header blocks with no
ENDkeyword. - Network reachability: CVSS vector
AV:N— the malicious asset can be delivered over a network (download, upload, shared pipeline location), though the parser itself runs locally within the consuming application. - User interaction:
UI:R— an operator or automated pipeline must feed the crafted stream to OpenImageIO.
Root Cause
The absence of a recursion-depth bound. The parser trusts that a well-formed FITS stream terminates its header block sequence. Malformed input violates that assumption, and the lack of a guard converts a malformed-data condition into a resource-exhaustion crash. This is a classic parser-hardening defect: correctness under adversarial input was not enforced with an explicit termination condition.
Exploitation Scenarios
No public PoC, Nuclei template, or exploit code is available for CVE-2026-59156. The attack chain below is inferred strictly from the vulnerability class and the details in the NVD description; no specific function names, paths, or parameters beyond those in the description are asserted.
Reconnaissance / Target Identification. The attacker identifies a target that ingests externally supplied FITS imagery through OpenImageIO — for example, a cloud image-conversion service, a render-farm ingest node, an automated VFX asset pipeline, or a desktop DCC/thumbnail/preview tool. Because OpenImageIO is a library rather than a standalone network service, the reachable surface is the host application that links it. Reconnaissance therefore focuses on finding an application endpoint or workflow that accepts image uploads and normalizes them via OpenImageIO.
Triggering the Flaw Class (Unbounded Recursion). The attacker crafts a FITS stream consisting of a long sequence of 2880-byte header blocks that never include the mandatory
ENDkeyword. This is a data-construction attack — no code execution primitive is required. The malformed structure directly violates the parser's termination assumption for the header-block sequence.Payload / Delivery. The crafted asset is delivered through whatever channel the target application exposes for image input: file upload, a shared/networked asset directory, an email attachment, or inclusion in a larger pipeline artifact. When the victim application (or an automated worker) processes the asset,
FitsInput::read_fits_header()re-enters itself once per unterminated 2880-byte block. Each re-entry adds a stack frame; the recursion proceeds without a depth bound.Post-Exploitation Impact. When the stack is exhausted, the process crashes with a stack-overflow fault. In a single-user desktop context this is an application crash and potential unsaved-work loss. In a service or render-farm context, the crash terminates a worker; if the same hostile asset is repeatedly re-ingested (e.g., it persists in a watched directory or shared inbox), this can produce a repeating crash loop that degrades throughput or availability. There is no privilege escalation, code execution, or data-exfiltration primitive in the described flaw — the sole impact is availability (denial of service).
Confidence note: The specific bytes-per-block (2880) and the missing-END condition are taken verbatim from the NVD description. The exact number of blocks needed to exhaust a given stack, and any per-process limits, are environment-dependent and not stated in the source data.
Impact Assessment
CVSS 3.1 Base Score: 6.5 (Medium). Subscore interpretation:
- Confidentiality: None (C:N). No data disclosure is possible from the described flaw.
- Integrity: None (I:N). The crash does not allow modification of data or code.
- Availability: High (A:H). Full process termination; potential repeated crash loop in automated ingestion contexts.
- Scope: Unchanged (S:U). Impact is confined to the vulnerable component's process.
- Attack Vector: Network (AV:N) / Complexity: Low (AC:L) / Privileges: None (PR:N) / User Interaction: Required (UI:R). The asset can travel over the network and is trivial to construct, but the target must process it.
Blast Radius
OpenImageIO is a dependency library, so the true blast radius equals the set of applications and services that link it for FITS handling. High-impact environments:
- VFX/animation studios: render nodes, ingest tooling, review/playback apps.
- Cloud rendering / media processing: multi-tenant conversion or thumbnail services where one malformed upload affects a shared worker.
- Automated pipelines: any watched directory or upload endpoint that parses untrusted imagery without sandboxing.
EPSS is not yet scored by FIRST.org; no exploit-in-the-wild or KEV evidence is available. Exploitation is low-cost but low-yield (denial of service only), which typically depresses real-world weaponization interest — though defacement/DoS is a common goal for opportunists targeting image-processing endpoints.
Detection Guidance
Detection combines (a) network inspection for FITS header-block patterns lacking END, and (b) host/application telemetry for crashes in OpenImageIO-consuming processes.
Sigma Rule
title: Potential OpenImageIO FITS Header Recursion DoS (CVE-2026-59156)
id: 3f9c1a72-5b2e-4c1d-9a7e-8d6f0b2c4e91
status: experimental
description: Detects process crashes consistent with stack exhaustion while parsing crafted FITS streams in OpenImageIO (unbounded recursion in FitsInput::read_fits_header).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-59156
author: valtersit.com
date: 2026/01/01
tags:
- attack.t1499
- cwe.674
logsource:
category: application
product: linux
detection:
selection_proc:
Image|endswith:
- 'oiiotool'
- 'OpenImageIO'
selection_fault:
- message|contains: 'stack overflow'
- message|contains: 'read_fits_header'
- message|contains: 'Segmentation fault'
condition: selection_proc and selection_fault
falsepositives:
- Legitimate deep recursion in unrelated image formats
- General application crashes
level: medium
YARA Rule
rule CVE_2026_59156_FITS_Unterminated_Header_Blocks
{
meta:
description = "Detects FITS streams with many consecutive 2880-byte header blocks lacking an END keyword, indicative of CVE-2026-59156 recursion DoS payloads"
author = "valtersit.com"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-59156"
cve = "CVE-2026-59156"
date = "2026-01-01"
strings:
$simple = "SIMPLE" ascii
$xtension = "XTENSION" ascii
$end = "END" ascii
condition:
// FITS primary header starts with SIMPLE or XTENSION at offset 0
($simple at 0 or $xtension at 0)
// Size is a multiple of the 2880-byte FITS block size and sizable,
// with no END keyword anywhere in the header region.
and (filesize % 2880 == 0)
and (filesize >= 2880 * 16)
and not $end
}
Suricata IDS Rule
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2026-59156 OpenImageIO FITS unterminated header block transfer (possible recursion DoS payload)"; flow:established,to_server; content:"SIMPLE"; depth:4; content:!"END"; app-layer-protocol:!tls; classtype:attempted-dos; reference:cve,2026-59156; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-59156; sid:5915601; rev:1;)
Note: FITS headers are plain ASCII within 2880-byte blocks; the negative END match and the SIMPLE header signature together approximate a payload where header blocks never terminate. Tune depth/offsets to your file-transfer protocol (FTP/SMB/HTTP body) as appropriate.
Elastic Detection
process where event.type == "end" and process.exit_code != 0 and
(process.name in ("oiiotool", "oiiotool-bin", "OpenImageIO") or
process.executable : "*OpenImageIO*") and
process.Ext.code_signature.exists == true
Companion crash-trace search (KQL) for the parser frame:
logs-* where message : "*read_fits_header*" and message : ("*stack overflow*" or "*stack-overflow*" or "*addresssanitizer*" or "*SIGSEGV*")
Splunk SPL Query
index=main sourcetype IN ("linux_messages","syslog","application_logs")
(process_name="oiiotool" OR process_name="OpenImageIO" OR process="*openimageio*")
(("read_fits_header" OR "FitsInput") AND ("stack" OR "segmentation" OR "core dumped" OR "SIGSEGV" OR "crash"))
| stats count min(_time) as first_seen max(_time) as last_seen by host, process_name, message
| where count >= 1
| eval first_seen=strftime(first_seen,"%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen,"%Y-%m-%d %H:%M:%S")
| sort - count
Alternative SPL to catch repeated worker deaths (crash loop indicator):
index=main sourcetype="application_logs" "oiiotool" ("core dumped" OR "SIGSEGV")
| bin _time span=5m
| stats count dc(host) as hosts by _time, process_name
| where count > 3
Wazuh OSSEC Rule
<group name="openimageio,attack,denial_of_service,">
<rule id="591560" level="8">
<decoded_as>syslog</decoded_as>
<match>read_fits_header|FitsInput</match>
<match>stack|segmentation|SIGSEGV|core dumped</match>
<description>CVE-2026-59156: OpenImageIO FITS header recursion crash detected (possible DoS)</description>
<mitre>
<id>T1499</id>
</mitre>
<group>cve_2026_59156,pci_dss_10.2.4,</group>
</rule>
<rule id="591561" level="10" frequency="5" timeframe="300">
<if_matched_sid>591560</if_matched_sid>
<description>CVE-2026-59156: Repeated OpenImageIO FITS crashes - probable ongoing DoS attempt</description>
<mitre>
<id>T1499</id>
</mitre>
<group>cve_2026_59156,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). The NVD description names fixed versions (3.0.20.0, 3.1.15.0, 3.2.0.3-beta1), but no vendor advisory, changelog, commit hash, or OSV entry has been confirmed. Treat patch references as claimed until independently verified against the upstream repository, and validate the fix by re-testing with your own malformed-FITS corpus.
1) Immediate Mitigations (do not wait for a verified patch)
- Sandbox FITS parsing. Run any OpenImageIO-consuming process that handles untrusted imagery inside a container or worker with a hard stack limit (
ulimit -s), memory cap, and restart-on-crash policy. Bounded resources convert a full-system crash into a contained worker restart. - Isolate and rate-limit ingest. Place image-conversion and pipeline-ingest services on non-critical hosts; throttle uploads and enforce per-source quotas to blunt crash-loop abuse.
- Fail fast on malformed FITS. If you control the ingest layer, pre-validate or reject FITS assets that lack an
ENDkeyword or that exceed a sane header-block count before handing them to OpenImageIO. - Drop/disable unnecessary format support. If FITS is not required in a given deployment, remove or disable the FITS reader to eliminate the attack surface entirely.
- Restrict asset sources. Only accept imagery from authenticated, trusted origins, since exploitation requires the victim to process the crafted stream (
UI:R).
2) Patch / Upgrade Steps
- Monitor the upstream OpenImageIO project and your distribution's security channels for a confirmed advisory covering CVE-2026-59156.
- When a verified release lands, upgrade the library and every application that statically or dynamically links it, to 3.0.20.0, 3.1.15.0, or 3.2.0.3-beta1 (or later) as applicable to your branch.
- Rebuild dependent binaries to ensure the patched
fitsinputcode is linked, and confirm the fix by re-running a malformed-FITS test case (consecutive 2880-byte blocks, noEND) against the new build.
3) Long-Term Hardening
- Adversarial parser testing. Add malformed FITS corpora (unterminated header blocks, oversized header sequences) to your CI fuzzing and regression suite.
- Resource-bounded parsing. Encourage/require an explicit recursion or iteration depth cap in FITS header parsing; treat unbounded recursion as a defect class (CWE-674) across other format readers.
- Dependency inventory. Maintain an SBOM so that third-party consumers of OpenImageIO (render nodes, DCC tools, cloud media services) can be identified and patched quickly.
- Defense in depth. Combine resource limits, process supervision, and network/asset controls so a single malformed file cannot take down an availability-critical workflow.
References
- NVD — CVE-2026-59156: https://nvd.nist.gov/vuln/detail/CVE-2026-59156
- MITRE CWE-674 — Uncontrolled Recursion: https://cwe.mitre.org/data/definitions/674.html
- MITRE ATT&CK T1499 — Endpoint Denial of Service: https://attack.mitre.org/techniques/T1499/
- OpenImageIO project (source for
src/fits.imageio/fitsinput.cppand release notes): https://github.com/AcademySoftwareFoundation/OpenImageIO - FITS standard (2880-byte header blocks / mandatory
ENDkeyword), FITS Standard documentation as maintained by the IAU FITS Working Group: https://fits.gsfc.nasa.gov/fits_standard.html
Threat-actor / in-the-wild status: No known threat actor campaigns, CISA KEV listing, public PoC, or exploit code are associated with CVE-2026-59156 at the time of writing. EPSS has not yet been scored by FIRST.org.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.