From 286c463968e9f55b4bd7a860161182fe55bc7632 Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Wed, 26 Mar 2025 22:03:02 +0100 Subject: [PATCH] CVE-2025-27516 --- Jinja2-2.10.1/jinja2/filters.py | 28 +++++++++++----------------- Jinja2-2.10.1/tests/test_security.py | 10 ++++++++++ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Jinja2-2.10.1/jinja2/filters.py b/Jinja2-2.10.1/jinja2/filters.py index 3e33f57..9816094 100644 --- a/Jinja2-2.10.1/jinja2/filters.py +++ b/Jinja2-2.10.1/jinja2/filters.py @@ -13,6 +13,7 @@ import math import random import warnings +from inspect import getattr_static from itertools import groupby, chain from collections import namedtuple from jinja2.utils import Markup, escape, pformat, urlize, soft_unicode, \ @@ -931,27 +932,20 @@ 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 ` for more details. """ 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) + 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 diff --git a/Jinja2-2.10.1/tests/test_security.py b/Jinja2-2.10.1/tests/test_security.py index 1719644..b2ba1a3 100644 --- a/Jinja2-2.10.1/tests/test_security.py +++ b/Jinja2-2.10.1/tests/test_security.py @@ -223,3 +223,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() -- 2.49.0