Restrict builtins for ImageMath.eval

This commit is contained in:
Andrew Murray 2022-01-02 17:23:49 +11:00
parent 1efb1d9fab
commit 8531b01d6c
3 changed files with 21 additions and 1 deletions

View File

@ -1,3 +1,5 @@
import pytest
from PIL import Image, ImageMath
@ -50,6 +52,11 @@ def test_ops():
assert pixel(ImageMath.eval("float(B)**33", images)) == "F 8589934592.0"
def test_prevent_exec():
with pytest.raises(ValueError):
ImageMath.eval("exec('pass')")
def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"

View File

@ -116,6 +116,14 @@ To prevent attempts to slow down loading times for images, if an image has conse
duplicate tiles that only differ by their offset, only load the last tile. Credit to
Google's `OSS-Fuzz`_ project for finding this issue.
Restrict builtins available to ImageMath.eval
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To limit :py:class:`PIL.ImageMath` to working with images, Pillow will now restrict the
builtins available to :py:meth:`PIL.ImageMath.eval`. This will help prevent problems
arising if users evaluate arbitrary expressions, such as
``ImageMath.eval("exec(exit())")``.
Fixed ImagePath.Path array handling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -246,7 +246,12 @@ def eval(expression, _dict={}, **kw):
if hasattr(v, "im"):
args[k] = _Operand(v)
out = builtins.eval(expression, args)
code = compile(expression, "<string>", "eval")
for name in code.co_names:
if name not in args and name != "abs":
raise ValueError(f"'{name}' not allowed")
out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args)
try:
return out.im
except AttributeError: