diff options
| author | Saravanan <saravanan.kadambathursubramaniyam@windriver.com> | 2025-10-13 17:22:44 +0530 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2025-10-24 06:23:39 -0700 |
| commit | 2ab1bedda9e081dbf01d4c3069d247efc6c3c55e (patch) | |
| tree | cfa19813920bfa49eb1059e23cbef19710625777 /meta/recipes-devtools/python/python3-xmltodict/CVE-2025-9375-1.patch | |
| parent | a04f9ab3a5f5d813b581a4dfa19ac21dd6c5ac67 (diff) | |
| download | poky-2ab1bedda9e081dbf01d4c3069d247efc6c3c55e.tar.gz | |
python3-xmltodict: fix CVE-2025-9375
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2025-9375
https://security-tracker.debian.org/tracker/CVE-2025-9375
https://git.launchpad.net/ubuntu/+source/python-xmltodict/commit/?id=e8110a20e00d80db31d5fc9f8f4577328385d6b6
Upstream-patch:
https://github.com/martinblech/xmltodict/commit/ecd456ab88d379514b116ef9293318b74e5ed3ee
https://github.com/martinblech/xmltodict/commit/f98c90f071228ed73df997807298e1df4f790c33
(From OE-Core rev: 30624cce634cade0b030aa71a03be754abbf3da9)
Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta/recipes-devtools/python/python3-xmltodict/CVE-2025-9375-1.patch')
| -rw-r--r-- | meta/recipes-devtools/python/python3-xmltodict/CVE-2025-9375-1.patch | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/meta/recipes-devtools/python/python3-xmltodict/CVE-2025-9375-1.patch b/meta/recipes-devtools/python/python3-xmltodict/CVE-2025-9375-1.patch new file mode 100644 index 0000000000..e8977dd2ea --- /dev/null +++ b/meta/recipes-devtools/python/python3-xmltodict/CVE-2025-9375-1.patch | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | From ecd456ab88d379514b116ef9293318b74e5ed3ee Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Martin Blech <78768+martinblech@users.noreply.github.com> | ||
| 3 | Date: Thu, 4 Sep 2025 17:25:39 -0700 | ||
| 4 | Subject: [PATCH] Prevent XML injection: reject '<'/'>' in element/attr names | ||
| 5 | (incl. @xmlns) | ||
| 6 | |||
| 7 | * Add tests for tag names, attribute names, and @xmlns prefixes; confirm attr values are escaped. | ||
| 8 | |||
| 9 | CVE: CVE-2025-9375 | ||
| 10 | |||
| 11 | Upstream-Status: Backport | ||
| 12 | https://github.com/martinblech/xmltodict/commit/ecd456ab88d379514b116ef9293318b74e5ed3ee | ||
| 13 | https://git.launchpad.net/ubuntu/+source/python-xmltodict/commit/?id=e8110a20e00d80db31d5fc9f8f4577328385d6b6 | ||
| 14 | |||
| 15 | Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com> | ||
| 16 | |||
| 17 | --- | ||
| 18 | tests/test_dicttoxml.py | 32 ++++++++++++++++++++++++++++++++ | ||
| 19 | xmltodict.py | 20 +++++++++++++++++++- | ||
| 20 | 2 files changed, 51 insertions(+), 1 deletion(-) | ||
| 21 | |||
| 22 | Index: python-xmltodict-0.13.0/tests/test_dicttoxml.py | ||
| 23 | =================================================================== | ||
| 24 | --- python-xmltodict-0.13.0.orig/tests/test_dicttoxml.py | ||
| 25 | +++ python-xmltodict-0.13.0/tests/test_dicttoxml.py | ||
| 26 | @@ -213,3 +213,35 @@ xmlns:b="http://b.com/"><x a:attr="val"> | ||
| 27 | expected_xml = '<?xml version="1.0" encoding="utf-8"?>\n<x>false</x>' | ||
| 28 | xml = unparse(dict(x=False)) | ||
| 29 | self.assertEqual(xml, expected_xml) | ||
| 30 | + | ||
| 31 | + def test_rejects_tag_name_with_angle_brackets(self): | ||
| 32 | + # Minimal guard: disallow '<' or '>' to prevent breaking tag context | ||
| 33 | + with self.assertRaises(ValueError): | ||
| 34 | + unparse({"m><tag>content</tag": "unsafe"}, full_document=False) | ||
| 35 | + | ||
| 36 | + def test_rejects_attribute_name_with_angle_brackets(self): | ||
| 37 | + # Now we expect bad attribute names to be rejected | ||
| 38 | + with self.assertRaises(ValueError): | ||
| 39 | + unparse( | ||
| 40 | + {"a": {"@m><tag>content</tag": "unsafe", "#text": "x"}}, | ||
| 41 | + full_document=False, | ||
| 42 | + ) | ||
| 43 | + | ||
| 44 | + def test_rejects_malicious_xmlns_prefix(self): | ||
| 45 | + # xmlns prefixes go under @xmlns mapping; reject angle brackets in prefix | ||
| 46 | + with self.assertRaises(ValueError): | ||
| 47 | + unparse( | ||
| 48 | + { | ||
| 49 | + "a": { | ||
| 50 | + "@xmlns": {"m><bad": "http://example.com/"}, | ||
| 51 | + "#text": "x", | ||
| 52 | + } | ||
| 53 | + }, | ||
| 54 | + full_document=False, | ||
| 55 | + ) | ||
| 56 | + | ||
| 57 | + def test_attribute_values_with_angle_brackets_are_escaped(self): | ||
| 58 | + # Attribute values should be escaped by XMLGenerator | ||
| 59 | + xml = unparse({"a": {"@attr": "1<middle>2", "#text": "x"}}, full_document=False) | ||
| 60 | + # The generated XML should contain escaped '<' and '>' within the attribute value | ||
| 61 | + self.assertIn('attr="1<middle>2"', xml) | ||
| 62 | Index: python-xmltodict-0.13.0/xmltodict.py | ||
| 63 | =================================================================== | ||
| 64 | --- python-xmltodict-0.13.0.orig/xmltodict.py | ||
| 65 | +++ python-xmltodict-0.13.0/xmltodict.py | ||
| 66 | @@ -379,6 +379,14 @@ def parse(xml_input, encoding=None, expa | ||
| 67 | return handler.item | ||
| 68 | |||
| 69 | |||
| 70 | +def _has_angle_brackets(value): | ||
| 71 | + """Return True if value (a str) contains '<' or '>'. | ||
| 72 | + | ||
| 73 | + Non-string values return False. Uses fast substring checks implemented in C. | ||
| 74 | + """ | ||
| 75 | + return isinstance(value, str) and ("<" in value or ">" in value) | ||
| 76 | + | ||
| 77 | + | ||
| 78 | def _process_namespace(name, namespaces, ns_sep=':', attr_prefix='@'): | ||
| 79 | if not namespaces: | ||
| 80 | return name | ||
| 81 | @@ -412,6 +420,9 @@ def _emit(key, value, content_handler, | ||
| 82 | if result is None: | ||
| 83 | return | ||
| 84 | key, value = result | ||
| 85 | + # Minimal validation to avoid breaking out of tag context | ||
| 86 | + if _has_angle_brackets(key): | ||
| 87 | + raise ValueError('Invalid element name: "<" or ">" not allowed') | ||
| 88 | if (not hasattr(value, '__iter__') | ||
| 89 | or isinstance(value, _basestring) | ||
| 90 | or isinstance(value, dict)): | ||
| 91 | @@ -445,12 +456,19 @@ def _emit(key, value, content_handler, | ||
| 92 | attr_prefix) | ||
| 93 | if ik == '@xmlns' and isinstance(iv, dict): | ||
| 94 | for k, v in iv.items(): | ||
| 95 | + if _has_angle_brackets(k): | ||
| 96 | + raise ValueError( | ||
| 97 | + 'Invalid attribute name: "<" or ">" not allowed' | ||
| 98 | + ) | ||
| 99 | attr = 'xmlns{}'.format(':{}'.format(k) if k else '') | ||
| 100 | attrs[attr] = _unicode(v) | ||
| 101 | continue | ||
| 102 | if not isinstance(iv, _unicode): | ||
| 103 | iv = _unicode(iv) | ||
| 104 | - attrs[ik[len(attr_prefix):]] = iv | ||
| 105 | + attr_name = ik[len(attr_prefix) :] | ||
| 106 | + if _has_angle_brackets(attr_name): | ||
| 107 | + raise ValueError('Invalid attribute name: "<" or ">" not allowed') | ||
| 108 | + attrs[attr_name] = iv | ||
| 109 | continue | ||
| 110 | children.append((ik, iv)) | ||
| 111 | if pretty: | ||
