Skip to main content

Entenda e mitigue a vulnerabilidade de XSS no Jinja2 (CVE-2024-22195)

Escrito por
feature open source

18 de janeiro de 2024

0 minutos de leitura

Em 11 de janeiro de 2024, foi divulgada uma vulnerabilidade de segurança significativa no Jinja2, uma biblioteca de templates Python amplamente utilizada. Identificada como CVE-2024-22195, essa vulnerabilidade de cross-site scripting (XSS) gerou preocupação devido ao impacto em inúmeros projetos. O Jinja2 tem mais de 33 milhões de downloads semanais, quase 10 mil estrelas no GitHub e é usado por mais de 90 mil projetos.

A vulnerabilidade afeta todas as versões anteriores à 3.1.3. A versão 3.1.3, que corrige o problema, é a única opção segura. Vale destacar que a versão mais baixada, a 3.1.2, continua vulnerável e é amplamente utilizada.

Painel de popularidade mostrando os downloads semanais por versão, com a versão 3.1.2 atingindo o pico de 17,42 milhões de downloads.

Como posso verificar se meu projeto está usando uma versão vulnerável do Jinja2?

Você pode verificar a versão do Jinja2 no arquivo requirements.txt ou executar pip list | grep Jinja2 no ambiente virtual do seu projeto.

Entenda como o Jinja2 é usado no desenvolvimento com Python

A popularidade do Jinja2 vem da possibilidade de criar templates HTML dinâmicos com uma sintaxe semelhante à do Python. A biblioteca oferece recursos como herança de templates, escape automático de HTML para prevenir XSS causado por entradas não confiáveis e suporte à internacionalização.

Em geral, desenvolvedores instalam a biblioteca pelo PyPI com o comando pip install Jinja2. Veja um exemplo de uso em um projeto:

{% 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 %}

Detalhes da vulnerabilidade de XSS

A CVE-2024-22195 é causada pelo filtro xmlattr do Jinja2 quando são usadas chaves com espaços provenientes de entradas do usuário. Essa falha permite que invasores injetem atributos HTML arbitrários nos templates, contornem o mecanismo de escape automático e, potencialmente, executem scripts não confiáveis no navegador do usuário.

A seguir, apresentamos uma reprodução completa de prova de conceito da vulnerabilidade de cross-site scripting no Jinja2, criada por Calum Hutton, da equipe de pesquisa de segurança da Snyk, que divulgou a vulnerabilidade:

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
    ))

Como reproduzir a vulnerabilidade de XSS Jinja2 CVE-2024-22195 

Crie um novo ambiente virtual com Python 3:

  1. python3 -m venv myenv 

  2. source myenv/bin/activate

Observação: se você ainda não conhece o gerenciamento de diferentes ambientes de desenvolvimento Python, recomendamos que reserve alguns minutos para ler sobre como dominar ambientes virtuais Python: um guia completo de venv, Docker e proteção do seu código.

Em seguida, crie o arquivo de dependências Python requirements.txt, usado pelo gerenciador de pacotes pip, e adicione bibliotecas comuns do registro PyPI:

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

Agora, podemos usar a Snyk para analisar o projeto e verificar se alguma das dependências Python está vulnerável. Se você usa macOS, instale primeiro a Snyk pelo brew, a maneira mais rápida de começar:

brew tap snyk/tap
brew install snyk

Observação: para outros sistemas operacionais, como Windows ou Linux, consulte as instruções de instalação na Snyk User Docs.

Você precisa se autenticar na Snyk. Execute snyk auth e siga as instruções para entrar pelo navegador. A Snyk CLI obterá automaticamente as credenciais da API para você.

Agora podemos analisar nosso projeto Python. Execute:

snyk test

Você verá os resultados encontrados pela 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

A Snyk detectou corretamente a versão vulnerável do Jinja2 usada no projeto (versão 3.1.2) e recomendou uma correção pela CLI.

Também vale lembrar que você pode usar uma extensão da Snyk no seu IDE para analisar seu próprio código Python e aplicações Python em contêineres, além de verificar dependências de terceiros do PyPI.

A vulnerabilidade de XSS no Jinja2 é fácil de explorar?

A complexidade da exploração dessa vulnerabilidade varia conforme a aplicação e a forma como ela implementa o Jinja2. No entanto, devido à natureza das vulnerabilidades de XSS, é recomendável tratá-la como prioridade alta.

Como mitigar a vulnerabilidade do Jinja2 e monitorar a segurança continuamente

Recomendamos que você atualize imediatamente para o Jinja2 versão 3.1.3 para corrigir essa vulnerabilidade.

Além disso, ferramentas como a Snyk são essenciais para monitorar vulnerabilidades continuamente. A Snyk detecta códigos e bibliotecas vulneráveis por meio da extensão para IDE e também é fundamental para analisar aplicações em contêineres Docker que incluem essa dependência vulnerável.

Como posso proteger meu projeto contra a vulnerabilidade XSS do Jinja2?

Atualize o Jinja2 para a versão 3.1.3 ou posterior. Para isso, altere o arquivo requirements.txt para Jinja2>=3.1.3 e execute pip install -U -r requirements.txt.

Recursos de segurança para desenvolvedores e próximos passos

A descoberta da CVE-2024-22195 no Jinja2 reforça a importância de manter as dependências atualizadas e usar ferramentas como a Snyk para monitorar a segurança continuamente. Ao se manterem informados e agirem de forma proativa, desenvolvedores podem proteger seus projetos contra vulnerabilidades como essa.

Aprenda sobre XSS em Python com Snyk Learn: XSS em Python

Guia rápido de boas práticas de segurança em Python: Boas práticas de segurança em Python

Como dominar ambientes virtuais Python: Ambientes virtuais Python

Boas práticas para conteinerizar aplicações Python com Docker: Conteinerização de Python com Docker

Há outras práticas de segurança recomendadas para quem usa Jinja2?

Além de manter o Jinja2 atualizado, siga as boas práticas gerais de segurança: valide e sanitize todas as entradas de usuários, implemente políticas de segurança de conteúdo e faça auditorias de segurança regularmente.