Merge pull request #5923 from radarhere/imagemath_eval

Restrict builtins for ImageMath.eval()
This commit is contained in:
mergify[bot] 2022-01-02 07:04:41 +00:00 committed by GitHub
commit d7f60d1d5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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: