File CVE-2025-27516.patch of Package python-Jinja2.37840

From 065334d1ee5b7210e1a0a93c37238c86858f2af7 Mon Sep 17 00:00:00 2001
From: David Lord <davidism@gmail.com>
Date: Wed, 5 Mar 2025 10:08:48 -0800
Subject: [PATCH] attr filter uses env.getattr

---
 jinja2/filters.py  | 37 ++++++++++++++++---------------------
 tests/test_security.py | 10 ++++++++++
 2 files changed, 26 insertions(+), 21 deletions(-)

Index: Jinja2-2.10.1/jinja2/filters.py
===================================================================
--- Jinja2-2.10.1.orig/jinja2/filters.py
+++ Jinja2-2.10.1/jinja2/filters.py
@@ -13,6 +13,7 @@ import re
 import math
 import random
 import warnings
+from inspect import getattr_static
 
 from itertools import groupby, chain
 from collections import namedtuple
@@ -934,27 +935,25 @@ def do_reverse(value):
 
 @environmentfilter
 def do_attr(environment, obj, name):
-    """Get an attribute of an object.  ``foo|attr("bar")`` works like
-    ``foo.bar`` just that always an attribute is returned and items are not
-    looked up.
+    """Get an attribute of an object. ``foo|attr("bar")`` works like
+    ``foo.bar``, but returns undefined instead of falling back to ``foo["bar"]``
+    if the attribute doesn't exist.
 
     See :ref:`Notes on subscriptions <notes-on-subscriptions>` for more details.
     """
+    # Environment.getattr will fall back to obj[name] if obj.name doesn't exist.
+    # But we want to call env.getattr to get behavior such as sandboxing.
+    # Determine if the attr exists first, so we know the fallback won't trigger.
     try:
-        name = str(name)
-    except UnicodeError:
-        pass
-    else:
-        try:
-            value = getattr(obj, name)
-        except AttributeError:
-            pass
-        else:
-            if environment.sandboxed and not \
-               environment.is_safe_attribute(obj, name, value):
-                return environment.unsafe_undefined(obj, name)
-            return value
-    return environment.undefined(obj=obj, name=name)
+        # This avoids executing properties/descriptors, but misses __getattr__
+        # and __getattribute__ dynamic attrs.
+        getattr_static(obj, name)
+    except AttributeError:
+        # This finds dynamic attrs, and we know it's not a descriptor at this point.
+        if not hasattr(obj, name):
+            return environment.undefined(obj=obj, name=name)
+
+    return environment.getattr(obj, name)
 
 
 @contextfilter
Index: Jinja2-2.10.1/tests/test_security.py
===================================================================
--- Jinja2-2.10.1.orig/tests/test_security.py
+++ Jinja2-2.10.1/tests/test_security.py
@@ -224,3 +224,13 @@ class TestStringFormatMap(object):
 
         with pytest.raises(SecurityError):
             t.render()
+
+    def test_attr_filter(self) -> None:
+        env = SandboxedEnvironment()
+        t = env.from_string(
+            """{{ "{0.__call__.__builtins__[__import__]}"
+                  | attr("format")(not_here) }}"""
+        )
+
+        with pytest.raises(SecurityError):
+            t.render()
openSUSE Build Service is sponsored by