1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Mon, 10 Jan 2022 21:49:55 +1100
X-Dgit-Generated: 8.1.2+dfsg-0.3+deb11u2 402664cf8c2ea7bb9353f52bca59171d42bdf330
Subject: Restrict builtins within lambdas for ImageMath.eval
(cherry picked from commit c930be0758ac02cf15a2b8d5409d50d443550581)
---
diff --git a/Tests/test_imagemath.py b/Tests/test_imagemath.py
index 239806796..09d5e1bc9 100644
--- a/Tests/test_imagemath.py
+++ b/Tests/test_imagemath.py
@@ -1,5 +1,7 @@
from PIL import Image, ImageMath
+import pytest
+
def pixel(im):
if hasattr(im, "im"):
@@ -50,6 +52,19 @@ def test_ops():
assert pixel(ImageMath.eval("float(B)**33", images)) == "F 8589934592.0"
+@pytest.mark.parametrize(
+ "expression",
+ (
+ "eval('pass')",
+ "(lambda: eval('pass'))()",
+ "(lambda: (lambda: eval('pass'))())()",
+ ),
+)
+def test_prevent_exec(expression):
+ with pytest.raises(ValueError):
+ ImageMath.eval(expression)
+
+
def test_logical():
assert pixel(ImageMath.eval("not A", images)) == 0
assert pixel(ImageMath.eval("A and B", images)) == "L 2"
diff --git a/src/PIL/ImageMath.py b/src/PIL/ImageMath.py
index 06bea800d..47ad3c9ae 100644
--- a/src/PIL/ImageMath.py
+++ b/src/PIL/ImageMath.py
@@ -246,11 +246,18 @@ def eval(expression, _dict={}, **kw):
if hasattr(v, "im"):
args[k] = _Operand(v)
- 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")
+ compiled_code = compile(expression, "<string>", "eval")
+ def scan(code):
+ for const in code.co_consts:
+ if type(const) == type(compiled_code):
+ scan(const)
+
+ for name in code.co_names:
+ if name not in args and name != "abs":
+ raise ValueError(f"'{name}' not allowed")
+
+ scan(compiled_code)
out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args)
try:
return out.im
|