VYPR
Moderate severityNVD Advisory· Published Jan 11, 2024· Updated Nov 3, 2025

Jinja vulnerable to Cross-Site Scripting (XSS)

CVE-2024-22195

Description

Jinja is an extensible templating engine. Special placeholders in the template allow writing code similar to Python syntax. It is possible to inject arbitrary HTML attributes into the rendered HTML template, potentially leading to Cross-Site Scripting (XSS). The Jinja xmlattr filter can be abused to inject arbitrary HTML attribute keys and values, bypassing the auto escaping mechanism and potentially leading to XSS. It may also be possible to bypass attribute validation checks if they are blacklist-based.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Jinja's xmlattr filter can be abused to inject arbitrary HTML attributes, bypassing autoescaping and leading to XSS.

Vulnerability

Jinja's xmlattr filter, used to render HTML attributes from a dictionary, fails to sanitize attribute keys, allowing injection of arbitrary HTML attributes. Since keys are not escaped, an attacker can inject attributes like event handlers (e.g., onclick) to bypass the autoescaping mechanism [1]. This bypass occurs because the filter escapes values but not keys, enabling the injection of malicious attribute names.

Exploitation

An attacker who can control the dictionary passed to the xmlattr filter can inject arbitrary attribute keys, including those with spaces or special characters. While the official fix prohibits keys with spaces [2], blacklist-based attribute validation may still be circumvented [1]. The attack requires the template to use the xmlattr filter with attacker-controlled input, such as user-provided data rendered in a template.

Impact

Successful exploitation leads to Cross-Site Scripting (XSS) by injecting arbitrary HTML attributes, allowing the attacker to execute malicious scripts in the context of the victim's browser. This can result in data theft, session hijacking, or other client-side attacks [1].

Mitigation

The vulnerability is fixed in Jinja version 3.1.3, which raises a ValueError if any attribute key contains a space [2][3]. Users should upgrade to this version or later. If upgrading is not possible, avoid using the xmlattr filter with untrusted data or implement strict key validation.

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.

PackageAffected versionsPatched versions
jinja2PyPI
< 3.1.33.1.3

Affected products

155

Patches

1
716795349a41

Merge pull request from GHSA-h5c8-rqwp-cp95

https://github.com/pallets/jinjaDavid LordJan 10, 2024via ghsa
3 files changed · +28 7
  • CHANGES.rst+1 0 modified
    @@ -7,6 +7,7 @@ Unreleased
     
     -   Fix compiler error when checking if required blocks in parent templates are
         empty. :pr:`1858`
    +-   ``xmlattr`` filter does not allow keys with spaces. GHSA-h5c8-rqwp-cp95
     
     
     Version 3.1.2
    
  • src/jinja2/filters.py+21 7 modified
    @@ -248,13 +248,17 @@ 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)
    +
    +
     @pass_eval_context
     def do_xmlattr(
         eval_ctx: "EvalContext", d: t.Mapping[str, t.Any], autospace: bool = True
     ) -> str:
         """Create an SGML/XML attribute string based on the items in a dict.
    -    All values that are neither `none` nor `undefined` are automatically
    -    escaped:
    +
    +    If any key contains a space, this fails with a ``ValueError``. Values that
    +    are neither ``none`` nor ``undefined`` are automatically escaped.
     
         .. sourcecode:: html+jinja
     
    @@ -273,12 +277,22 @@ 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.3
    +        Keys with spaces are not allowed.
         """
    -    rv = " ".join(
    -        f'{escape(key)}="{escape(value)}"'
    -        for key, value in d.items()
    -        if value is not None and not isinstance(value, Undefined)
    -    )
    +    items = []
    +
    +    for key, value in d.items():
    +        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}'")
    +
    +        items.append(f'{escape(key)}="{escape(value)}"')
    +
    +    rv = " ".join(items)
     
         if autospace and rv:
             rv = " " + rv
    
  • tests/test_filters.py+6 0 modified
    @@ -474,6 +474,12 @@ def test_xmlattr(self, env):
             assert 'bar="23"' in out
             assert 'blub:blub="&lt;?&gt;"' 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()
    +
         def test_sort1(self, env):
             tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}")
             assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

13

News mentions

0

No linked articles in our index yet.