InsightSoftwareConsortium / InsightSoftwareConsortium/ITK

Fuzz the IO readers: untrusted file parsers have no fuzzing and no sanitizer CI leg

Open
#6,818 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
1.7k
Forks
748
Avg merge
1d 1h
Merged PRs (30d)
64

Description

## Summary

ITK's IO readers parse untrusted files and are not fuzzed. Four defects of the same class were found on 2026-08-28 by reading code for a few hours — #6813, #6815, #6816, #6817 — including out-of-bounds stack reads reachable from a three-line text header. Hand-auditing found them; hand-auditing will not keep finding them, and will not stop them recurring.

OpenSSF Scorecard currently reports **Fuzzing: 0 — "no fuzzer integrations found"** for ITK (run `2026-08-27`, v5.1.1). This is one of the unchecked boxes in #5084, open since 2024-12-17.

## Why IO readers are the right first target

Image file headers are the project's clearest trust boundary: a user opens a dataset obtained from a scanner, a collaborator, or a public archive. The reader must treat every field as hostile, and a survey of 19 IO modules found the ITK-parsed readers do so inconsistently:

- **#6815** — `numDim: 9` in a Stimulate `.spr` header reads past four length-4 uninitialized stack arrays; adjacent stack bytes become the image's spacing and origin.
- **#6813** — Bruker: `VisuCoreOrientation` consumed as nine doubles regardless of how many the file supplied; frame counts and slope arrays used without cardinality checks.
- **#6816** — VTK legacy: the `COLOR_SCALARS` component count reaches the buffer allocation unvalidated.
- **#6817** — `ImageIOBase`: geometry setters validate the axis index but never the value, and `GetImageSizeInPixels()` multiplies dimensions with no overflow check.

Every one of these is the kind of defect a coverage-guided fuzzer finds in minutes. None required a sophisticated input.

## Current state

- **No fuzz harness in the repository.** `grep -ril fuzz` outside `.git/` and `Modules/ThirdParty/` matches only release notes, Doxygen config, a bibliography, `UpdateZenodo.py`, and a wrapping exclude list.
- **ITK is not in OSS-Fuzz.** The only `oss-fuzz` references in-tree are inside vendored dependencies (OpenJPEG, zlib-ng, Expat, libtiff) — ITK's *dependencies* are fuzzed upstream; ITK's own readers are not.
- **No sanitizer CI leg.** No `asan|ubsan|tsan|valgrind|sanitiz` match in any `.github/workflows/` file; the only hits are vendored CMake (`itkhdf5`, `itkzlib-ng/cmake/detect-sanitizer.cmake`, NIFTI).
- Sanitizer findings do reach the tracker, but ad hoc from individuals rather than from CI — #2353, #5467, #3210 open; #5026, #4655, #3031, #1478, #5415, #4448 closed.

## Suggested shape

A minimal, self-contained starting point that does not require OSS-Fuzz onboarding:

1. **One libFuzzer harness per ITK-parsed reader**, taking a byte buffer, writing it to a temp file, and calling `ReadImageInformation()` + `Read()` inside a `try`/`catch(itk::ExceptionObject &)`. An ITK exception is a **pass** — the contract being fuzzed is "malformed input produces an `itk::ExceptionObject`, never a crash, a hang, or a silent wrong answer."
2. **Seed corpora** from the existing per-format test data already in `Testing/Data` — no new data required.
3. **A CI leg** running the harnesses under ASan+UBSan for a bounded time budget on PRs, longer nightly.
4. **OSS-Fuzz submission** once the harnesses are stable, which also addresses the Scorecard check directly.

Prioritize by trust boundary and by whether ITK does the parsing. These parse headers in ITK code and should come first: Stimulate; Bruker; VTK legacy; the GE / IPL / Siemens family; BMP; MRC.

GDCM, NIFTI, NRRD, MINC, MetaIO, JPEG, PNG, TIFF and JPEG2000 delegate to vendored libraries that are separately fuzzed upstream — lower priority here, though ITK's handling of the values those libraries return is still in scope (see #6817).

## Note on scope

Deliberately narrower than #5084, which tracks the full OpenSSF checklist. Fuzzing is broken out because it has a concrete, demonstrated payload — four defects filed the same day this was written — and because it is actionable independently of the other checklist items.

Contributor guide

Open the contributing guide

Research direction

Start with the suggested reader priority and inspect the existing per-format test data in Testing/Data, then review .github/workflows and parent issue #5084 for current CI conventions. Done means adding fuzz harnesses for the targeted ITK-parsed readers, using the existing seed corpora, and establishing the proposed bounded ASan+UBSan CI coverage without crashes, hangs, or silent wrong answers.

Written by the indexing model from the issue text.

Assessment

Tech stack
cmake, cpp, github-actions
Domain
ci-cd, security, testing-qa
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.