Jinja vulnerable to HTML attribute injection when passing user input as keys to xmlattr filter
Description
Jinja is an extensible templating engine. The xmlattr filter in affected versions of Jinja accepts keys containing non-attribute characters. XML/HTML attributes cannot contain spaces, /, >, or =, as each would then be interpreted as starting a separate attribute. If an application accepts keys (as opposed to only values) as user input, and renders these in pages that other users see as well, an attacker could use this to inject other attributes and perform XSS. The fix for CVE-2024-22195 only addressed spaces but not other characters. Accepting keys as user input is now explicitly considered an unintended use case of the xmlattr filter, and code that does so without otherwise validating the input should be flagged as insecure, regardless of Jinja version. Accepting _values_ as user input continues to be safe. This vulnerability is fixed in 3.1.4.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Jinja's xmlattr filter allows attribute injection via keys containing special characters, enabling XSS when user input is used as keys; fixed in 3.1.4.
What the vulnerability is: The xmlattr filter in Jinja templating engine fails to properly sanitize keys for XML/HTML attributes. According to the HTML specification, attribute names cannot contain spaces, /, >, or = as these characters would break the attribute syntax and allow injection of additional attributes [1][2]. The previous fix for CVE-2024-22195 only addressed spaces, leaving the other characters unblocked [1].
How it is exploited: An attacker can supply a key containing characters like /, >, or = to the xmlattr filter. If an application accepts user input as attribute keys (rather than only values) and renders the output in a page viewed by other users, the attacker can inject arbitrary HTML attributes. This can lead to cross-site scripting (XSS) by injecting event handlers or other malicious attributes [1][2].
Impact: Successful exploitation allows an attacker to perform XSS attacks, potentially stealing cookies, session tokens, or performing actions on behalf of the victim. The Jinja project explicitly states that accepting user input as keys to xmlattr is an unintended use case and should be considered insecure regardless of version [1][2].
Mitigation: The vulnerability is fixed in Jinja version 3.1.4, which now rejects keys containing any of the forbidden characters [2]. Users should upgrade to 3.1.4 or later. Additionally, applications should never use user input as keys to xmlattr without thorough validation [1][2].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
Jinja2PyPI | < 3.1.4 | 3.1.4 |
Affected products
115- osv-coords114 versionspkg:apk/chainguard/checkovpkg:apk/chainguard/confluent-docker-utilspkg:apk/chainguard/dask-gatewaypkg:apk/chainguard/dask-gateway-serverpkg:apk/chainguard/kubeflow-jupyter-web-apppkg:apk/chainguard/kubeflow-pipelines-visualization-serverpkg:apk/chainguard/kubeflow-volumes-web-apppkg:apk/chainguard/nemopkg:apk/chainguard/py3.10-jinja2pkg:apk/chainguard/py3.11-jinja2pkg:apk/chainguard/py3.12-jinja2pkg:apk/chainguard/py3.13-jinja2pkg:apk/chainguard/py3-jinja2pkg:apk/chainguard/py3-supported-jinja2pkg:apk/chainguard/pytorchpkg:apk/chainguard/reflexpkg:apk/chainguard/supersetpkg:apk/chainguard/superset-cipkg:apk/chainguard/superset-entrypointpkg:apk/chainguard/superset-iamguarded-compatpkg:apk/wolfi/checkovpkg:apk/wolfi/confluent-docker-utilspkg:apk/wolfi/dask-gatewaypkg:apk/wolfi/dask-gateway-serverpkg:apk/wolfi/kubeflow-jupyter-web-apppkg:apk/wolfi/kubeflow-pipelines-visualization-serverpkg:apk/wolfi/kubeflow-volumes-web-apppkg:apk/wolfi/py3.10-jinja2pkg:apk/wolfi/py3.11-jinja2pkg:apk/wolfi/py3.12-jinja2pkg:apk/wolfi/py3.13-jinja2pkg:apk/wolfi/py3-jinja2pkg:apk/wolfi/py3-supported-jinja2pkg:apk/wolfi/pytorchpkg:apk/wolfi/reflexpkg:apk/wolfi/supersetpkg:apk/wolfi/superset-cipkg:apk/wolfi/superset-entrypointpkg:apk/wolfi/superset-iamguarded-compatpkg:pypi/jinja2pkg:rpm/almalinux/fence-agents-aliyunpkg:rpm/almalinux/fence-agents-allpkg:rpm/almalinux/fence-agents-amt-wspkg:rpm/almalinux/fence-agents-apcpkg:rpm/almalinux/fence-agents-apc-snmppkg:rpm/almalinux/fence-agents-awspkg:rpm/almalinux/fence-agents-azure-armpkg:rpm/almalinux/fence-agents-bladecenterpkg:rpm/almalinux/fence-agents-brocadepkg:rpm/almalinux/fence-agents-cisco-mdspkg:rpm/almalinux/fence-agents-cisco-ucspkg:rpm/almalinux/fence-agents-commonpkg:rpm/almalinux/fence-agents-computepkg:rpm/almalinux/fence-agents-drac5pkg:rpm/almalinux/fence-agents-eaton-snmppkg:rpm/almalinux/fence-agents-emersonpkg:rpm/almalinux/fence-agents-epspkg:rpm/almalinux/fence-agents-gcepkg:rpm/almalinux/fence-agents-heuristics-pingpkg:rpm/almalinux/fence-agents-hpbladepkg:rpm/almalinux/fence-agents-ibmbladepkg:rpm/almalinux/fence-agents-ibm-powervspkg:rpm/almalinux/fence-agents-ibm-vpcpkg:rpm/almalinux/fence-agents-ifmibpkg:rpm/almalinux/fence-agents-ilo2pkg:rpm/almalinux/fence-agents-ilo-moonshotpkg:rpm/almalinux/fence-agents-ilo-mppkg:rpm/almalinux/fence-agents-ilo-sshpkg:rpm/almalinux/fence-agents-intelmodularpkg:rpm/almalinux/fence-agents-ipdupkg:rpm/almalinux/fence-agents-ipmilanpkg:rpm/almalinux/fence-agents-kdumppkg:rpm/almalinux/fence-agents-kubevirtpkg:rpm/almalinux/fence-agents-lparpkg:rpm/almalinux/fence-agents-mpathpkg:rpm/almalinux/fence-agents-openstackpkg:rpm/almalinux/fence-agents-redfishpkg:rpm/almalinux/fence-agents-rhevmpkg:rpm/almalinux/fence-agents-rsapkg:rpm/almalinux/fence-agents-rsbpkg:rpm/almalinux/fence-agents-sbdpkg:rpm/almalinux/fence-agents-scsipkg:rpm/almalinux/fence-agents-virshpkg:rpm/almalinux/fence-agents-vmware-restpkg:rpm/almalinux/fence-agents-vmware-soappkg:rpm/almalinux/fence-agents-wtipkg:rpm/almalinux/fence-agents-zvmpkg:rpm/almalinux/fence-virtpkg:rpm/almalinux/fence-virtdpkg:rpm/almalinux/fence-virtd-cpgpkg:rpm/almalinux/fence-virtd-libvirtpkg:rpm/almalinux/fence-virtd-multicastpkg:rpm/almalinux/fence-virtd-serialpkg:rpm/almalinux/fence-virtd-tcppkg:rpm/almalinux/ha-cloud-supportpkg:rpm/almalinux/python3-jinja2pkg:rpm/opensuse/python-Jinja2&distro=openSUSE%20Leap%2015.5pkg:rpm/opensuse/python-Jinja2&distro=openSUSE%20Leap%2015.6pkg:rpm/opensuse/python-Jinja2&distro=openSUSE%20Leap%20Micro%205.3pkg:rpm/opensuse/python-Jinja2&distro=openSUSE%20Leap%20Micro%205.4pkg:rpm/opensuse/python-Jinja2&distro=openSUSE%20Tumbleweedpkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Micro%205.1pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Micro%205.2pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Micro%205.3pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Micro%205.4pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Micro%205.5pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Advanced%20Systems%20Management%2012pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Basesystem%2015%20SP5pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Basesystem%2015%20SP6pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Public%20Cloud%2012pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Python%203%2015%20SP5pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Python%203%2015%20SP6pkg:rpm/suse/python-Jinja2&distro=SUSE%20Linux%20Micro%206.0pkg:rpm/suse/python-Jinja2&distro=SUSE%20Manager%20Client%20Tools%2012
< 3.0.34-r1+ 113 more
- (no CPE)range: < 3.0.34-r1
- (no CPE)range: < 0.0.77-r0
- (no CPE)range: < 2024.1.0-r4
- (no CPE)range: < 2024.1.0-r4
- (no CPE)range: < 1.8.0-r7
- (no CPE)range: < 2.4.0-r0
- (no CPE)range: < 1.8.0-r6
- (no CPE)range: < 1.23.0-r12
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 2.3.0-r0
- (no CPE)range: < 0.5.0-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 3.0.34-r1
- (no CPE)range: < 0.0.77-r0
- (no CPE)range: < 2024.1.0-r4
- (no CPE)range: < 2024.1.0-r4
- (no CPE)range: < 1.8.0-r7
- (no CPE)range: < 2.4.0-r0
- (no CPE)range: < 1.8.0-r6
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 3.1.4-r1
- (no CPE)range: < 2.3.0-r0
- (no CPE)range: < 0.5.0-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 4.0.1-r0
- (no CPE)range: < 3.1.4
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 4.10.0-62.el9_4.3
- (no CPE)range: < 2.10.1-5.el8_10
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 3.1.2-150400.12.6.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 3.1.4-1.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.8-19.26.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.10.1-150000.3.13.1
- (no CPE)range: < 2.8-19.26.1
- (no CPE)range: < 3.1.2-150400.12.6.1
- (no CPE)range: < 3.1.2-150400.12.6.1
- (no CPE)range: < 3.1.2-6.1
- (no CPE)range: < 2.8-19.26.1
- pallets/jinjav5Range: < 3.1.4
Patches
10668239dc6b4Merge pull request from GHSA-h75v-3vvj-5mfj
3 files changed · +29 −10
CHANGES.rst+6 −0 modified@@ -5,6 +5,12 @@ Version 3.1.4 Unreleased +- The ``xmlattr`` filter does not allow keys with ``/`` solidus, ``>`` + greater-than sign, or ``=`` equals sign, in addition to disallowing spaces. + Regardless of any validation done by Jinja, user input should never be used + as keys to this filter, or must be separately validated first. + GHSA-h75v-3vvj-5mfj + Version 3.1.3 -------------
src/jinja2/filters.py+17 −5 modified@@ -250,7 +250,9 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K yield from value.items() -_space_re = re.compile(r"\s", flags=re.ASCII) +# Check for characters that would move the parser state from key to value. +# https://html.spec.whatwg.org/#attribute-name-state +_attr_key_re = re.compile(r"[\s/>=]", flags=re.ASCII) @pass_eval_context @@ -259,8 +261,14 @@ def do_xmlattr( ) -> str: """Create an SGML/XML attribute string based on the items in a dict. - If any key contains a space, this fails with a ``ValueError``. Values that - are neither ``none`` nor ``undefined`` are automatically escaped. + **Values** that are neither ``none`` nor ``undefined`` are automatically + escaped, safely allowing untrusted user input. + + User input should not be used as **keys** to this filter. If any key + contains a space, ``/`` solidus, ``>`` greater-than sign, or ``=`` equals + sign, this fails with a ``ValueError``. Regardless of this, user input + should never be used as keys to this filter, or must be separately validated + first. .. sourcecode:: html+jinja @@ -280,6 +288,10 @@ def do_xmlattr( As you can see it automatically prepends a space in front of the item if the filter returned something unless the second parameter is false. + .. versionchanged:: 3.1.4 + Keys with ``/`` solidus, ``>`` greater-than sign, or ``=`` equals sign + are not allowed. + .. versionchanged:: 3.1.3 Keys with spaces are not allowed. """ @@ -289,8 +301,8 @@ def do_xmlattr( if value is None or isinstance(value, Undefined): continue - if _space_re.search(key) is not None: - raise ValueError(f"Spaces are not allowed in attributes: '{key}'") + if _attr_key_re.search(key) is not None: + raise ValueError(f"Invalid character in attribute name: {key!r}") items.append(f'{escape(key)}="{escape(value)}"')
tests/test_filters.py+6 −5 modified@@ -474,11 +474,12 @@ def test_xmlattr(self, env): assert 'bar="23"' in out assert 'blub:blub="<?>"' in out - def test_xmlattr_key_with_spaces(self, env): - with pytest.raises(ValueError, match="Spaces are not allowed"): - env.from_string( - "{{ {'src=1 onerror=alert(1)': 'my_class'}|xmlattr }}" - ).render() + @pytest.mark.parametrize("sep", ("\t", "\n", "\f", " ", "/", ">", "=")) + def test_xmlattr_key_invalid(self, env: Environment, sep: str) -> None: + with pytest.raises(ValueError, match="Invalid character"): + env.from_string("{{ {key: 'my_class'}|xmlattr }}").render( + key=f"class{sep}onclick=alert(1)" + ) def test_sort1(self, env): tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}")
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
13- github.com/advisories/GHSA-h75v-3vvj-5mfjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-34064ghsaADVISORY
- github.com/pallets/jinja/commit/0668239dc6b44ef38e7a6c9f91f312fd4ca581cbghsax_refsource_MISCWEB
- github.com/pallets/jinja/security/advisories/GHSA-h75v-3vvj-5mfjghsax_refsource_CONFIRMWEB
- lists.debian.org/debian-lts-announce/2024/12/msg00009.htmlghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/567XIGSZMABG6TSMYWD7MIYNJSUQQRUCghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/GCLF44KY43BSVMTE6S53B4V5WP3FRRSEghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SSCBHIL6BYKR5NRCBXP4XMP2CEEKGFVSghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZALNWE3TXPPHVPSI3AZ5CTMSTAVN5UMSghsaWEB
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/567XIGSZMABG6TSMYWD7MIYNJSUQQRUC/mitre
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/GCLF44KY43BSVMTE6S53B4V5WP3FRRSE/mitre
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SSCBHIL6BYKR5NRCBXP4XMP2CEEKGFVS/mitre
- lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/ZALNWE3TXPPHVPSI3AZ5CTMSTAVN5UMS/mitre
News mentions
0No linked articles in our index yet.