Alta

ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp

  • Publicada: 07.10.2026
  • Actualizado: 12.10.2026 17:17

Summary

When decoding a fax-compressed strip TIFF (Compression=3 / Group 3 1D, or Compression=2 / Modified Huffman), the CCITT decompressors write decoded runs through BitWriterUtils.WriteBits/WriteBit/WriteZeroBit, which advance and write bits via Unsafe.Add with read-modify-write semantics — without ever comparing the write position against the target buffer length. The strip buffer is sized ImageWidth × RowsPerStrip (8 bytes in the PoC), but two independent defects let an attacker write tens of millions of bits past it: (a) T4 only increments rowsWritten when an EOL code is read, and one ReadNextRun accumulates unlimited makeup codes (+2560 px per 12-bit code) into a single RunLength that WritePixelRun then writes in one shot; (b) Modified Huffman writes before validating (pixelsWritten > Width is checked at :90-93, after the write at :56-63), so the overflow completes even though an exception is thrown later. One crafted ~90 KB file writes ~19.2 MB linearly past an 8-byte buffer and deterministically kills the process; the write offset and length are fully attacker-controlled (classic heap-corruption primitive on the managed heap).

Verified at commit 5cd4d0d26a82a9549f297a237aea9cf665bddff8 (main; latest release v4.1.0, the supported major). A related tiled-path variant (tile-buffer width mismatch) was reported separately as GHSA-v76p-62qx-wwq2 — this report covers the distinct strip-path root cause.

Details

Root cause: the bit-writing sink has no bounds check, and neither decompressor constrains run lengths against the strip buffer.

Attack surface: Image.Load(stream) on an attacker-supplied strip TIFF (TiffDecoderCore.DecodeStripsChunky → TiffDecompressorsFactory.Create → Decompress). Default configuration, no authentication, no user interaction — a plain strip TIFF (far more common than the tiled variant) with Compression=2 or 3 and a chain of CCITT makeup codes.

Relationship to GHSA-v76p-62qx-wwq2: that report is the tiled variant — a caller-side width mismatch (TiffDecompressorsFactory drops tile parameters) that overflows with perfectly legal run codes. This report is the strip variant — the callee-side missing bounds check plus T4's EOL-only row accounting and MH's write-before-validate. Fixing the caller mismatch does not address this vector; bounding BitWriterUtils addresses both (see remediation).

Suggested remediation:

  1. Bound BitWriterUtils.WriteBits/WriteBit/WriteZeroBit against buffer.Length*8 (return bool / throw ImageFormatException) — do not rely on caller discipline.
  2. In the T4/MH decompress loops, validate (bitsWritten + RunLength) <= buffer.Length*8 before writing; abort T4 when accumulated rows exceed stripHeight instead of waiting for the loop to end naturally.
  3. In Modified Huffman, move the pixelsWritten > Width check before the actual write.
  4. Regression fuzz cases: Compression=2/3, EOL-less oversized makeup chains, edge widths; strip and tiled paths share the same constraint.

PoC

Full PoC posted as the first comment below: Program.cs (driver), poc-tiff-t4.tif + poc-tiff-mh.tif (crafted files, ~90 KB each, base64 inline), README.

  1. Build a console project referencing src/ImageSharp/ImageSharp.csproj, run it against either crafted file (or call Image.Load on it).

  2. PoC layout: TIFF (II, 42), ImageWidth=64, ImageLength=1, BitsPerSample=1, Photometric=WhiteIsZero, RowsPerStrip=1; strip data = EOL(12bit) + 60000× white makeup 2560 (000000011111) + white terminating code (000111) — declared run ≈ 153,600,001 px ≈ 19.2 MB into an 8-byte buffer.

  3. Observed (both variants):

    strip payload 90003 bytes, claimed run ~153,600,001 px = 19,200,000 bytes into 8-byte buffer
    Fatal error. System.AccessViolationException: Attempted to read or write protected memory.
       at SixLabors.ImageSharp.Formats.Tiff.Compression.BitWriterUtils.WriteBits(Span`1<Byte>, IntPtr, IntPtr, Byte)
       at ...ModifiedHuffmanTiffCompression.Decompress(...)
       at SixLabors.ImageSharp.Formats.Tiff.TiffDecoderCore.DecodeStripsChunky[Rgba32](...)
    Aborted (core dumped); exit=134

    The T4 variant crashes identically at T4TiffCompression.WritePixelRun → BitWriterUtils.WriteBits.

  4. Control: an equivalent file without the makeup chain (legal EOL-delimited rows) decodes normally — the crash comes from the oversized runs, not the container.

Impact

  • What it is: out-of-bounds write (CWE-787). For any service decoding untrusted TIFFs (image hosting/transcoding/thumbnails/CMS): reliable remote DoS (uncatchable fatal process crash), plus a heap OOB write with attacker-controlled offset and length — a realistic heap-corruption / potential code-execution surface. In scope of your SECURITY.md as a library vulnerability.
  • Who is impacted: applications decoding untrusted TIFF with SixLabors.ImageSharp at the current major (verified on main past v4.1.0); plain strip TIFFs with Compression=2/3 are the trigger, which ordinary TIFF writers can produce.


Reported by Kimi Security Team (bug-report@moonshot.ai).

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
.NET (NuGet) ImageSharp >= 3.0.0, < 3.2.0, >= 4.0.0, < 4.1.1 3.2.0, 4.1.1

Referencias

Puntuación CVSS 7.5/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Debilidad (CWE)
CWE-787
Plataforma
.NET (NuGet)
Paquete
ImageSharp
Publicada
07.10.2026
Actualizado
12.10.2026 17:17

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-jj3q-cwqj-842r - CC BY 4.0

Historial de vulnerabilidades: ImageSharp

Todas las vulnerabilidades publicadas de este paquete (.NET (NuGet)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Entradas en total
2
Primera → última
10.2026 10.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Alta 2

Divulgaciones por año

  1. 2026: 2
  1. ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp esta entrada
    Alta · 7.5 CVE-2026-106117 >= 3.0.0, < 3.2.0, >= 4.0.0, < 4.1.1 3.2.0, 4.1.1

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.