|
| 1 | +From 5dcbbc98a404f70b4cedc8b3ff92a1859cc4cce5 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Sudipta Pandit <sudpandit@microsoft.com> |
| 3 | +Date: Wed, 22 May 2024 16:44:03 +0530 |
| 4 | +Subject: [PATCH] Backport upstream change for CVE-2024-34064 |
| 5 | + |
| 6 | +Backported from https://github.com/pallets/jinja/commit/0668239dc6b44ef38e7a6c9f91f312fd4ca581cb |
| 7 | +based on existing patch for CVE-2024-22195 |
| 8 | + |
| 9 | +Original patch: |
| 10 | +From d655030770081e2dfe46f90e27620472a502289d Mon Sep 17 00:00:00 2001 |
| 11 | +From: David Lord <davidism@gmail.com> |
| 12 | +Date: Thu, 2 May 2024 09:14:00 -0700 |
| 13 | +Subject: [PATCH] disallow invalid characters in keys to xmlattr filter |
| 14 | +--- |
| 15 | + src/jinja2/filters.py | 22 +++++++++++++++++----- |
| 16 | + tests/test_filters.py | 11 ++++++----- |
| 17 | + 2 files changed, 23 insertions(+), 10 deletions(-) |
| 18 | + |
| 19 | +diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py |
| 20 | +index 4f90bfe..28199e1 100644 |
| 21 | +--- a/src/jinja2/filters.py |
| 22 | ++++ b/src/jinja2/filters.py |
| 23 | +@@ -271,7 +271,9 @@ def do_lower(s: str) -> str: |
| 24 | + return soft_str(s).lower() |
| 25 | + |
| 26 | + |
| 27 | +-_space_re = re.compile(r"\s", flags=re.ASCII) |
| 28 | ++# Check for characters that would move the parser state from key to value. |
| 29 | ++# https://html.spec.whatwg.org/#attribute-name-state |
| 30 | ++_attr_key_re = re.compile(r"[\s/>=]", flags=re.ASCII) |
| 31 | + |
| 32 | + |
| 33 | + @pass_eval_context |
| 34 | +@@ -282,8 +284,14 @@ def do_xmlattr( |
| 35 | + All values that are neither `none` nor `undefined` are automatically |
| 36 | + escaped: |
| 37 | + |
| 38 | +- If any key contains a space, this fails with a ``ValueError``. Values that |
| 39 | +- are neither ``none`` nor ``undefined`` are automatically escaped. |
| 40 | ++ **Values** that are neither ``none`` nor ``undefined`` are automatically |
| 41 | ++ escaped, safely allowing untrusted user input. |
| 42 | ++ |
| 43 | ++ User input should not be used as **keys** to this filter. If any key |
| 44 | ++ contains a space, ``/`` solidus, ``>`` greater-than sign, or ``=`` equals |
| 45 | ++ sign, this fails with a ``ValueError``. Regardless of this, user input |
| 46 | ++ should never be used as keys to this filter, or must be separately validated |
| 47 | ++ first. |
| 48 | + |
| 49 | + .. sourcecode:: html+jinja |
| 50 | + |
| 51 | +@@ -303,6 +311,10 @@ def do_xmlattr( |
| 52 | + As you can see it automatically prepends a space in front of the item |
| 53 | + if the filter returned something unless the second parameter is false. |
| 54 | + |
| 55 | ++ .. versionchanged:: 3.1.4 |
| 56 | ++ Keys with ``/`` solidus, ``>`` greater-than sign, or ``=`` equals sign |
| 57 | ++ are not allowed. |
| 58 | ++ |
| 59 | + .. versionchanged:: 3.1.3 |
| 60 | + Keys with spaces are not allowed. (patched for 3.0.3) |
| 61 | + """ |
| 62 | +@@ -312,8 +324,8 @@ def do_xmlattr( |
| 63 | + if value is None or isinstance(value, Undefined): |
| 64 | + continue |
| 65 | + |
| 66 | +- if _space_re.search(key) is not None: |
| 67 | +- raise ValueError(f"Spaces are not allowed in attributes: '{key}'") |
| 68 | ++ if _attr_key_re.search(key) is not None: |
| 69 | ++ raise ValueError(f"Invalid character in attribute name: {key!r}") |
| 70 | + |
| 71 | + items.append(f'{escape(key)}="{escape(value)}"') |
| 72 | + |
| 73 | +diff --git a/tests/test_filters.py b/tests/test_filters.py |
| 74 | +index 45843fd..6533370 100644 |
| 75 | +--- a/tests/test_filters.py |
| 76 | ++++ b/tests/test_filters.py |
| 77 | +@@ -463,11 +463,12 @@ class TestFilter: |
| 78 | + assert 'bar="23"' in out |
| 79 | + assert 'blub:blub="<?>"' in out |
| 80 | + |
| 81 | +- def test_xmlattr_key_with_spaces(self, env): |
| 82 | +- with pytest.raises(ValueError, match="Spaces are not allowed"): |
| 83 | +- env.from_string( |
| 84 | +- "{{ {'src=1 onerror=alert(1)': 'my_class'}|xmlattr }}" |
| 85 | +- ).render() |
| 86 | ++ @pytest.mark.parametrize("sep", ("\t", "\n", "\f", " ", "/", ">", "=")) |
| 87 | ++ def test_xmlattr_key_invalid(self, env: Environment, sep: str) -> None: |
| 88 | ++ with pytest.raises(ValueError, match="Invalid character"): |
| 89 | ++ env.from_string("{{ {key: 'my_class'}|xmlattr }}").render( |
| 90 | ++ key=f"class{sep}onclick=alert(1)" |
| 91 | ++ ) |
| 92 | + |
| 93 | + def test_sort1(self, env): |
| 94 | + tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}") |
| 95 | +-- |
| 96 | +2.34.1 |
| 97 | + |
0 commit comments