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 from PIL import Image, ImageMath
@ -50,6 +52,11 @@ def test_ops():
assert pixel(ImageMath.eval("float(B)**33", images)) == "F 8589934592.0" 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(): def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0 assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2" 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 duplicate tiles that only differ by their offset, only load the last tile. Credit to
Google's `OSS-Fuzz`_ project for finding this issue. 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 Fixed ImagePath.Path array handling
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -246,7 +246,12 @@ def eval(expression, _dict={}, **kw):
if hasattr(v, "im"): if hasattr(v, "im"):
args[k] = _Operand(v) 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: try:
return out.im return out.im
except AttributeError: except AttributeError: