Skip to content
Security & Trust

Three Pillow flaws let a crafted image file attack Python services

OX Security reports CVE-2026-112900, CVE-2026-112393 and CVE-2026-112403, all fixed in Pillow 13.0.0

W
WebPulse Newsroom
AI-assisted · 4 min read
Share on X LinkedIn
Three Pillow flaws let a crafted image file attack Python services
In brief
  • OX Security reports three Pillow flaws, rated CVSS 9.2, where a crafted EPS, TIFF or JPEG file can cause command execution or memory corruption in Python services.
  • Pillow handles user uploads in many services, so exposure depends on how your code uses it, such as which formats it accepts and whether Ghostscript is installed.
  • Upgrade to Pillow 13.0.0 or later, rebuild containers that bundle it, and ask engineering which services open untrusted images.

A file upload button looks like a small feature. A customer adds a profile photo, or a staff member attaches a scan. Behind that button, your software has to open a file written by a stranger. The risk sits in the code that reads it, and that code is often a library nobody on the team chose by name.

OX Security has published details of three flaws in Pillow, a widely used Python library for handling images. They show how much trust a routine upload places in a dependency.

What OX Security reported

OX's researchers describe three vulnerabilities, rated CVSS 9.2 and disclosed on October 19, 2026. A crafted EPS, TIFF or JPEG file can lead to command execution or corrupted memory in a Python service that processes user-supplied images. All three are fixed in Pillow 13.0.0.

The three identifiers are CVE-2026-112900 (EPS argument injection leading to remote code execution), CVE-2026-112393 (a TIFF write overflow) and CVE-2026-112403 (a JPEG overflow in downscaling).

OX estimates Pillow gets 436 million downloads a month. It calls the library close to ubiquitous. In its account, Pillow sits underneath web frameworks, profile-photo and thumbnail features, document tooling and most Python machine-learning and vision software, whether installed on purpose or brought in by another package. The report does not say whether attacks are under way.

How each flaw works

The EPS flaw is the most unusual. Pillow renders EPS files by calling Ghostscript, a separate program. It passes the file name after a "-f" option without turning it into a full path. A file name that starts with a dash is then read by Ghostscript as an option, not a name.

Ghostscript also lets an at-sign point to a file whose contents become extra options. OX says an attacker who controls the file name Pillow opens, and the contents of that file, can inject options and run commands. This works even under Ghostscript's default "-dSAFER" setting. It applies only when the Ghostscript binary, "gs", is installed on the host.

The TIFF flaw is a sizing error. When Pillow saves a compressed TIFF to an in-memory buffer such as Python's BytesIO, it grows the buffer based on the previous buffer size, not the current write position. For output above 64 KiB, the underlying library can write past the end of the allocation. OX says this is a heap overflow, and it can also expose stale bytes from memory. Saving to a real file path is not affected.

The JPEG flaw is a mismatch between two measurements. Pillow's decoder writes a full-width line of pixels into a buffer sized from the tile or draft dimensions, not from the JPEG header. A crafted 8-bit lossless JPEG, sent to an application that downsizes through "draft()" or "thumbnail()", makes the decoder produce lines wider than the buffer. OX says the result is a crash and potentially code execution.

Whether the bad file gets through also depends on the underlying JPEG library. OX says older libjpeg-turbo 2.x and IJG versions refuse the malformed file, while newer libjpeg-turbo versions let it pass.

The pattern: trust is set by the dependency, not the feature

Each flaw needs a specific setup. The EPS issue needs control of a file name and Ghostscript on the host. The TIFF issue needs an in-memory save. The JPEG issue needs downscaling. That makes your exposure a question of how your code uses Pillow, not whether you have it.

That is the useful lesson here. This is our observation, not a finding of the report. Many teams may not be able to say which image formats their upload paths accept, or whether a Ghostscript binary sits on the same host. Image handling often arrives as a side effect of another package, so no one may own the decision.

OX notes that machine-learning and computer-vision stacks often include Pillow. Teams building pipelines that ingest images at volume may carry this library without a deliberate choice.

What to ask your team

OX's first step is to move to Pillow 13.0.0 or later. An upgrade on the server alone may miss copies of Pillow that ship inside packaged builds. OX says those builds, such as containers and base images, have to be produced again with the new version. OX calls this the only complete fix for all three flaws.

Then put these questions to engineering:

First, which services open user-supplied images, and which Pillow version does each one run, including inside container images? Second, does any host that handles untrusted uploads have Ghostscript installed? OX advises removing it where it is not needed. Third, which image formats do we accept, and do we need all of them? OX recommends accepting only the formats you use. Fourth, where do we call "draft()" or "thumbnail()" on untrusted JPEGs, or save TIFFs to memory? OX names these as the sensitive paths.

An upload form is a standing invitation to run a stranger's data through your code. The upgrade closes three doors. The inventory of what else your code opens is the lasting work.

Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: OX Security.

Share this insight