CVE-2024-42005 en Django: una SQL injection oculta detrás de JSONField

Publicado el 2026-10-27 por frfrand

Cómo surgió un fallo de SQL injection en Django QuerySet, a qué versiones afectó, cuándo hay exposición y qué corregir.

CVE-2024-42005 en Django: una SQL injection oculta detrás de JSONField

¿El ORM de Django evita todas las inyecciones SQL?

Un ORM ayuda muchísimo, pero no convierte cualquier entrada externa en segura. CVE-2024-42005, corregida por Django en agosto de 2024, muestra un caso concreto: ciertas llamadas a QuerySet.values() y values_list() sobre modelos con JSONField podían producir inyección SQL cuando se usaban claves de JSON preparadas maliciosamente como argumentos de columna.

¿Qué hace JSONField?

Permite guardar y consultar datos con estructura JSON en una columna. Es útil para configuraciones y atributos variables; por ejemplo, el perfil de un producto con características distintas. El problema aparece cuando se usa el nombre de un campo o una clave de JSON como parte de la estructura de una consulta, en vez de tratarlo únicamente como dato validado.

¿Quién lo detectó?

Django documentó la vulnerabilidad en sus notas oficiales del 6 de agosto de 2024. Para investigar este tipo de defecto se inspecciona cómo se genera SQL a partir de métodos del ORM y se prueban identificadores especiales, alias y entradas inesperadas. Si necesitás conocer la autoría exacta del hallazgo, consultá el registro oficial; no conviene inventar créditos de investigación.

¿Cómo podría aprovecharse?

Imaginá un endpoint que deja al usuario elegir campos de una respuesta y pasa esos nombres directamente a values(). Si el modelo usa JSONField y los nombres pueden manipular los alias SQL, el usuario podría influir sobre la consulta. No se activa por el simple hecho de tener Django y PostgreSQL instalados: hacen falta las funciones y el flujo de entrada pertinentes.

¿Por qué importa tanto si Django suele parametrizar?

Las consultas parametrizadas protegen valores, pero identificadores y alias pueden requerir otra clase de validación. Confiar en una función segura para valores cuando en realidad se está construyendo estructura SQL es un error habitual. El impacto depende de los permisos del usuario de base de datos y de qué operaciones permite la consulta afectada.

¿Qué versiones se corrigieron?

Las notas de Django señalan las correcciones en 5.0.8 y 4.2.15. Son versiones de referencia del boletín de 2024. Para 2026 elegí una rama aún mantenida y revisá sus avisos; no congeles una aplicación en una release antigua.

¿Cómo revisar si tu proyecto Django está expuesto?

Buscá usos de values(), values_list() y modelos con JSONField. Investigá especialmente endpoints que aceptan desde la API nombres de campos, ordenamientos o selecciones dinámicas. Confirmá que hay una lista permitida de nombres definidos por el desarrollador en vez de pasar cadenas del cliente a la consulta. Las pruebas deben cubrir entradas extrañas y permisos del rol SQL.

¿Cómo corregirlo?

Actualizá Django; validá los campos que un cliente puede solicitar; usá permisos mínimos en la base; añadí tests de regresión y revisá funciones auxiliares que generan consultas dinámicas. Si hay sospecha de abuso, conservá logs y analizá las operaciones realmente ejecutadas antes de determinar alcance.

Preguntas rápidas

¿Afecta a todos los modelos? No: el escenario documentado involucra modelos con JSONField y argumentos específicos.

¿Basta con escapar manualmente la cadena? No. Es más seguro validar un conjunto cerrado de identificadores y actualizar el framework.

¿Tener DRF cambia algo? Depende de cómo la vista transforma parámetros de usuario en operaciones QuerySet.

Fuentes: Notas Django 5.0.8 · Notas Django 4.2.15 · Registro CVE.

¿Dónde seguir alertas CVE y recibir orientación?

En ArduMaker CVE y soporte publicamos actualizaciones y centralizamos consultas sobre vulnerabilidades, comenzando por WordPress y sus tecnologías relacionadas. Si tu caso involucra otro runtime o una base de datos, especificá componente, versión, sistema operativo y exposición del servicio para contextualizarlo. El aviso de una CVE no prueba que tu servidor esté comprometido: la evaluación requiere inventario, configuración y evidencia.

Nota editorial — octubre de 2026: estas versiones corregidas son los hitos del aviso original. Al actualizar hoy, elegí una rama con soporte vigente y verificá el comunicado actual del fabricante.

Ejemplo práctico: elegir campos dinámicos de Django sin confiar en el usuario

Situación: una API de productos admite ?campo=id&campo=nombre y transforma cada parámetro directamente en argumentos de QuerySet.values(). Si esos nombres provienen de usuarios, deben validarse, especialmente cuando se combina con JSONField.

Ejemplo simplificado con lista permitida:

CAMPOS_PERMITIDOS = {"id", "nombre", "estado"}

solicitados = request.GET.getlist("campo")
if not solicitados or any(c not in CAMPOS_PERMITIDOS for c in solicitados):
    return JsonResponse({"error": "Campo no permitido"}, status=400)

filas = list(Producto.objects.values(*solicitados))
return JsonResponse({"resultados": filas})

Antes: pasar sin control nombres enviados por el cliente al ORM. Después: actualizar Django, validar identificadores contra una lista cerrada y usar un rol SQL sin privilegios de administración.

Importante: el ejemplo ilustra una defensa a nivel de aplicación; el fix oficial de CVE-2024-42005 sigue siendo necesario. Probá también qué sucede con solicitudes vacías, campos repetidos y claves JSON arbitrarias.

CVE-2024-42005 en Django: una SQL injection oculta detrás de JSONField
  • Django
  • Python
  • CVE-2024-42005
  • SQL injection
  • Backend

Seguir leyendo

Todos los artículos · Planes de VPS