CVE-2022-22817 highlights a serious security issue in the popular Python image processing library, Pillow. This vulnerability allows attackers to execute arbitrary Python code on a victim’s system by abusing the PIL.ImageMath.eval function. Let’s break down what happened, how exploitation works, and what you can do to stay safe.
What is Pillow and ImageMath.eval?
Pillow is a widely-used Python library for opening, manipulating, and saving images. Many websites, applications, and automation scripts use Pillow for image processing.
The PIL.ImageMath.eval function is designed to evaluate simple mathematical expressions on images, such as "a + b" where a and b are image bands (think: layers). However, until version 9.., this function evaluated expressions using Python’s built-in eval() without proper sanitization or restrictions.
Explaining the Vulnerability
In code, eval can run any string as Python code. If that string comes from an untrusted or user-controlled source, it’s a classic recipe for disaster—remote code execution (RCE). With Pillow versions before 9.., an attacker could sneak in code through the expression argument.
Here’s a simple, dangerous example
from PIL import ImageMath
# Suppose untrusted user input is used
user_input = "__import__('os').system('touch /tmp/pwned')"
result = ImageMath.eval(user_input)
This would create a file named /tmp/pwned—just an example. An attacker could replace 'touch /tmp/pwned' with any system command, or even worse, launch malicious payloads.
Getting Practical
If you or your web service use user-supplied strings in ImageMath.eval, attackers can craft their input to execute arbitrary code.
Simple Lambda Exploit
PIL.ImageMath.eval also supports expressions involving lambdas (anonymous functions). Attackers could pass a lambda expression to achieve the same effect:
from PIL import ImageMath
# Attacker-controlled input
user_input = "(lambda: __import__('os').system('ls /; cat /etc/passwd'))()"
result = ImageMath.eval(user_input)
This would list the root directory and output /etc/passwd, a classic information disclosure vector on Unix-like systems.
Setup persistence mechanisms
Any system running Pillow <9.. and directly or indirectly passing untrusted input to ImageMath.eval is *at risk*.
How Was It Fixed?
Pillow maintainers addressed this in version 9..:
> "ImageMath.eval now restricts evaluation input to safe Python expressions. It no longer allows the use of functions such as exec or lambda."
The patch restricts what expressions can be evaluated, blocking dangerous functions or modules.
Responsible Disclosure & References
- CVE Record - CVE-2022-22817
- Pillow Release Notes for 9.. (23 Dec 2021)
- Pillow GitHub PR #5916 (Fix for exec/lambda in eval)
- Exploit Database Entry
Final Thoughts
The PIL.ImageMath.eval vulnerability is a strong reminder: *never trust user input*, especially when it gets anywhere near an eval function. If you run or maintain a Python application that deals with image uploads or manipulation, *auditing your Pillow version and usage is critical*.
Always keep dependencies up-to-date, stay aware of security advisories, and review your code for risky patterns.
Timeline
Published on: 01/10/2022 14:12:00 UTC
Last modified on: 04/22/2022 16:21:00 UTC