{"id":"CVE-2026-106117","revision":null,"records":[{"revision":"ff3b95bb2463473caad65f8420cae20f","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-106117","aliases":[],"title":"ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp","description":"ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.","state":0,"publishedAt":"2026-10-06T17:53:46.448+00:00","modifiedAt":"2026-10-06T18:20:09.862+00:00","affected":[{"ecosystem":"Vendor product","name":"ImageSharp","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"SixLabors\",\n                    \"product\": \"ImageSharp\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 3.0.0, < 4.1.1\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5,"severity":"HIGH"}],"references":["https://github.com/SixLabors/ImageSharp/security/advisories/GHSA-jj3q-cwqj-842r","https://github.com/SixLabors/ImageSharp/pull/3176","https://github.com/SixLabors/ImageSharp/commit/e8892ecd8a95dee95c4480fda51cfe0b32f3b846","https://github.com/SixLabors/ImageSharp/releases/tag/v4.1.1"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-106117","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-106117","identifiers":["CVE-2026-106117"]},"retained":false,"historicalAffected":[]},{"revision":"e08aeb3a6b224684abd2bb8e530e100b","observedAt":"2026-10-30T01:52:03.89+00:00","statement":{"source":"euvd","id":"EUVD-2026-93560","aliases":["CVE-2026-106117","GHSA-jj3q-cwqj-842r"],"title":"ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width.…","description":"ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5,"severity":null}],"references":["https://github.com/SixLabors/ImageSharp/security/advisories/GHSA-jj3q-cwqj-842r","https://github.com/SixLabors/ImageSharp/pull/3176","https://github.com/SixLabors/ImageSharp/commit/e8892ecd8a95dee95c4480fda51cfe0b32f3b846","https://github.com/SixLabors/ImageSharp/releases/tag/v4.1.1"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-93560","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Oct 6, 2026, 5:53:46 PM","dateUpdated":"Oct 6, 2026, 6:20:09 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-93560","identifiers":["EUVD-2026-93560","CVE-2026-106117","GHSA-jj3q-cwqj-842r"]},"retained":false,"historicalAffected":[]},{"revision":"119f5c9cbab2416e94ffc4e8406ee762","observedAt":"2026-10-29T05:48:21.551+00:00","statement":{"source":"nvd","id":"CVE-2026-106117","aliases":[],"title":"ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width.…","description":"ImageSharp is a 2D graphics library. From 3.0.0 until 4.1.1, decoding a strip TIFF using CCITT Group 3 or Modified Huffman compression can pass attacker-expanded runs to BitWriterUtils.WriteBits without first checking the current row width. T4TiffCompression.WritePixelRun can accumulate oversized makeup-code runs, and ModifiedHuffmanTiffCompression.Decompress validates the width only after writing. The unchecked writes can overflow the strip buffer, corrupt heap memory, and terminate the process. This strip-path vulnerability is distinct from the tiled decompressor-width mismatch. This issue is fixed in version 4.1.1.","state":0,"publishedAt":"2026-10-06T18:16:53.55+00:00","modifiedAt":"2026-10-27T20:11:46.843+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":7.5,"severity":"HIGH"}],"references":["https://github.com/SixLabors/ImageSharp/commit/e8892ecd8a95dee95c4480fda51cfe0b32f3b846","https://github.com/SixLabors/ImageSharp/pull/3176","https://github.com/SixLabors/ImageSharp/releases/tag/v4.1.1","https://github.com/SixLabors/ImageSharp/security/advisories/GHSA-jj3q-cwqj-842r"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-106117","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Analyzed","weaknesses":["CWE-787"],"productCriteria":["cpe:2.3:a:sixlabors:imagesharp:*:*:*:*:*:*:*:*"],"sourceDates":{"published":"2026-10-06T18:16:53.550","lastModified":"2026-10-27T20:11:46.843"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-106117","identifiers":["CVE-2026-106117"]},"retained":false,"historicalAffected":[]},{"revision":"76d3381cd701479d9d16109b4184004f","observedAt":"2026-10-23T16:01:25.029+00:00","statement":{"source":"osv","id":"GHSA-jj3q-cwqj-842r","aliases":["CVE-2026-106117"],"title":"ImageSharp: CCITT fax decompression (T4/Modified Huffman): unbounded WriteBits overflows strip buffer — heap OOB write in SixLabors.ImageSharp","description":"## Summary\n\nWhen 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).\n\nVerified 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.\n\n## Details\n\nRoot cause: the bit-writing sink has no bounds check, and neither decompressor constrains run lengths against the strip buffer.\n\n- Unchecked write primitive: [BitWriterUtils.cs#L51](https://github.com/SixLabors/ImageSharp/blob/5cd4d0d26a82a9549f297a237aea9cf665bddff8/src/ImageSharp/Formats/Tiff/Compression/BitWriterUtils.cs#L51) (`WriteBit`), :58 (`WriteZeroBit` — also read-modify-write, so even all-white runs really write), :11 (`WriteBits`)\n- T4 trigger: [T4TiffCompression.cs#L75](https://github.com/SixLabors/ImageSharp/blob/5cd4d0d26a82a9549f297a237aea9cf665bddff8/src/ImageSharp/Formats/Tiff/Compression/Decompressors/T4TiffCompression.cs#L75) and L109-L119 — `rowsWritten` only increments on EOL; consecutive makeup codes accumulate into one `RunLength`, then `WritePixelRun` writes it in full\n- MH trigger: [ModifiedHuffmanTiffCompression.cs#L56-L63](https://github.com/SixLabors/ImageSharp/blob/5cd4d0d26a82a9549f297a237aea9cf665bddff8/src/ImageSharp/Formats/Tiff/Compression/Decompressors/ModifiedHuffmanTiffCompression.cs#L56-L63) — write happens before the width check at L90-L93\n- Buffer size: [TiffDecoderCore.cs#L932-L967](https://github.com/SixLabors/ImageSharp/blob/5cd4d0d26a82a9549f297a237aea9cf665bddff8/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs#L932-L967) — `CalculateStripBufferSize` = width × bpp/8 × rowsPerStrip\n\nAttack 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.\n\nRelationship 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).\n\n**Suggested remediation:**\n1. Bound `BitWriterUtils.WriteBits/WriteBit/WriteZeroBit` against `buffer.Length*8` (return bool / throw `ImageFormatException`) — do not rely on caller discipline.\n2. 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.\n3. In Modified Huffman, move the `pixelsWritten > Width` check before the actual write.\n4. Regression fuzz cases: Compression=2/3, EOL-less oversized makeup chains, edge widths; strip and tiled paths share the same constraint.\n\n## PoC\n\nFull 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.\n\n1. Build a console project referencing `src/ImageSharp/ImageSharp.csproj`, run it against either crafted file (or call `Image.Load` on it).\n2. 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.\n3. Observed (both variants):\n\n   ```\n   strip payload 90003 bytes, claimed run ~153,600,001 px = 19,200,000 bytes into 8-byte buffer\n   Fatal error. System.AccessViolationException: Attempted to read or write protected memory.\n      at SixLabors.ImageSharp.Formats.Tiff.Compression.BitWriterUtils.WriteBits(Span`1<Byte>, IntPtr, IntPtr, Byte)\n      at ...ModifiedHuffmanTiffCompression.Decompress(...)\n      at SixLabors.ImageSharp.Formats.Tiff.TiffDecoderCore.DecodeStripsChunky[Rgba32](...)\n   Aborted (core dumped); exit=134\n   ```\n\n   The T4 variant crashes identically at `T4TiffCompression.WritePixelRun → BitWriterUtils.WriteBits`.\n4. Control: an equivalent file without the makeup chain (legal EOL-delimited rows) decodes normally — the crash comes from the oversized runs, not the container.\n\n## Impact\n\n- **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.\n- **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.\n\n---\n\n---\n\nReported by **Kimi Security Team** (bug-report@moonshot.ai).","state":0,"publishedAt":"2026-10-07T16:18:50+00:00","modifiedAt":"2026-10-12T14:45:06.7014575+00:00","affected":[{"ecosystem":"NuGet","name":"ImageSharp","ranges":[{"type":"ECOSYSTEM","events":[{"kind":"introduced","version":"3.0.0"},{"kind":"fixed","version":"3.2.0"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"NuGet","name":"ImageSharp","ranges":[{"type":"ECOSYSTEM","events":[{"kind":"introduced","version":"4.0.0"},{"kind":"fixed","version":"4.1.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/SixLabors/ImageSharp/security/advisories/GHSA-jj3q-cwqj-842r","https://nvd.nist.gov/vuln/detail/CVE-2026-106117","https://github.com/SixLabors/ImageSharp/pull/3176","https://github.com/SixLabors/ImageSharp/commit/e8892ecd8a95dee95c4480fda51cfe0b32f3b846","https://github.com/SixLabors/ImageSharp","https://github.com/SixLabors/ImageSharp/releases/tag/v3.2.0","https://github.com/SixLabors/ImageSharp/releases/tag/v4.1.1"],"sourceUrl":"https://github.com/advisories/GHSA-jj3q-cwqj-842r","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-jj3q-cwqj-842r","identifiers":["GHSA-jj3q-cwqj-842r","CVE-2026-106117"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-10-31T19:04:56.1330465+00:00","complete":true,"records":1766,"lastAttemptAt":"2026-10-31T19:04:56.1330465+00:00","lastSuccessAt":"2026-10-31T19:04:56.2887005+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:56.2887022+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-9266d7b009bf9c4a0ccdcb5cbdea7f905cb3c4d92fd3b41581ece16b2cfdc4e7-c71479685b1713e2042fb88ec15880046552dd37e95ce2a15e200aae212a9461","complete":true,"records":417592,"lastAttemptAt":"2026-10-31T19:04:55.457276+00:00","lastSuccessAt":"2026-10-31T19:04:55.3095682+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:55.457276+00:00","snapshotPublishedAt":"2026-10-31T18:19:52+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-e7b141564b3340aebe07d7339b385d4a","complete":true,"records":13567,"lastAttemptAt":"2026-10-31T19:05:27.0056627+00:00","lastSuccessAt":"2026-10-31T19:05:27.002+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:05:27.002+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13637,"expectedIdentifiers":13637,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-10-31T19:04:56.1330465+00:00","complete":true,"records":1094,"lastAttemptAt":"2026-10-31T19:04:56.1330465+00:00","lastSuccessAt":"2026-10-31T19:04:56.2895472+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:56.289548+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-a558c2e000674838b5341fe81ce273de","complete":false,"records":13580,"lastAttemptAt":"2026-10-31T19:05:21.5191534+00:00","lastSuccessAt":"2026-10-31T19:05:21.516+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:05:21.516+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13636,"expectedIdentifiers":13637,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-21dcd6662970dfea02e4ea60ee637115e8d92664947484d2b9276b3f6568a84f","complete":true,"records":9815,"lastAttemptAt":"2026-10-31T19:04:56.081418+00:00","lastSuccessAt":"2026-10-30T23:47:34.1817587+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:56.081418+00:00","snapshotPublishedAt":"2026-10-30T23:33:17+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-2de9ccc5290f060c7aa63f89c25dd76f655a64ba1aba7c05c97fa3bee4f09899","complete":true,"records":1967,"lastAttemptAt":"2026-10-31T19:04:55.5925297+00:00","lastSuccessAt":"2026-10-28T20:55:34.2982937+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:55.5925297+00:00","snapshotPublishedAt":"2026-10-28T20:03:08+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-f95f76cd406ae5bae3de632ad37fd2d5160b44f5e6b51748ac6f8f0c0c88e72b","complete":true,"records":3028,"lastAttemptAt":"2026-10-31T19:04:56.0947894+00:00","lastSuccessAt":"2026-10-30T23:47:38.4914494+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:56.0947894+00:00","snapshotPublishedAt":"2026-10-30T23:18:12+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-712291bb5a0ee4f1ca7325e317f98ff05e9ab8d14f863abf00a323d9e6d8331e","complete":true,"records":230994,"lastAttemptAt":"2026-10-31T19:04:55.7662022+00:00","lastSuccessAt":"2026-10-31T17:06:47.8999408+00:00","error":null,"lastVerifiedAt":"2026-10-31T19:04:55.7662022+00:00","snapshotPublishedAt":"2026-10-31T16:33:38+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}