Auswirkungen der Änderung von Djangos SECRET_KEY

202

Ich habe einen Fehler gemacht und meine Django-Projekte SECRET_KEYin einem öffentlichen Repository gespeichert.

Dieser Schlüssel sollte gemäß den Dokumenten https://docs.djangoproject.com/de/dev/ref/settings/#std:setting-SECRET_KEY geheim gehalten werden

Das Django-Projekt ist live und läuft seit einiger Zeit mit einigen aktiven Benutzern. Was sind die Auswirkungen, wenn ich das ändere SECRET_KEY? Sind vorhandene Benutzer, Cookies, Sitzungen usw. betroffen? Offensichtlich wird das Neue SECRET_KEYnicht mehr an einem öffentlichen Ort aufbewahrt.

Derek Kwok
quelle

Antworten:

199

Bearbeiten: Diese Antwort basiert auf Django 1.5

SECRET_KEY wird an vielen verschiedenen Orten verwendet. Ich werde zuerst darauf hinweisen, was davon betroffen ist, und dann versuchen, diese Liste durchzugehen und die Auswirkungen genau zu erklären.

Die Liste der Dinge, die SECRET_KEYdirekt oder indirekt verwendet werden:

In der Realität nutzen viele der hier aufgeführten SECRET_KEYdurch django.utils.crypt.get_random_string()denen es verwendet den Zufall Motor auf Saatgut. Dies wird durch eine Wertänderung von nicht beeinflusst SECRET_KEY.

Die Benutzererfahrung, die direkt von einer Wertänderung betroffen ist, ist:

  • In Sitzungen wird die Datendecodierung unterbrochen, die für jedes Sitzungs-Backend (Cookies, Datenbank, dateibasiert oder Cache) gültig ist.
  • Das bereits gesendete Token zum Zurücksetzen des Passworts funktioniert nicht. Benutzer müssen ein neues Token anfordern.
  • Das Kommentarformular (falls verwendet django.contrib.comments) wird nicht validiert, wenn es vor der Wertänderung angefordert und nach der Wertänderung übermittelt wurde. Ich denke, das ist sehr geringfügig, könnte aber für den Benutzer verwirrend sein.
  • Nachrichten (von django.contrib.messages) werden serverseitig nicht unter den gleichen Zeitbedingungen wie für das Kommentarformular validiert.

UPDATE : Wenn ich jetzt an Django 1.9.5 arbeite, gibt mir ein kurzer Blick auf die Quelle so ziemlich die gleichen Antworten. Könnte später eine gründliche Inspektion durchführen.

sberder
quelle
1
Ich ändere SECRET_KEY auf meinem lokalen Entwicklungsserver und das meldet mich nicht ab. Es scheint also, dass zumindest Sitzungen (Cache) nach der Änderung korrekt funktionieren. Könnten Sie bitte näher data decode will breakdarauf eingehen, was Sie damit meinen, und vielleicht auf einen Code (in Django oder Beispielprojekt) hinweisen, der kaputt geht? EDIT: immer noch mit Django 1.4 - ist das der Fall?
Kirill Zaitsev
@teferi Ich weiß nichts über 1.4, es geht darum, einen Blick auf den Code zu werfen. Ich habe auf alle Quellen für jeden Punkt hingewiesen. Sie können einen Blick auf "Sitzungsdaten schützen und zufällige Sitzungsschlüssel erstellen" werfen. Es ist normal , Sie noch angemeldet sind , aber Sie werden nicht gelesen werden können , die in der Sitzung enthaltenen Daten wie SECRET_KEYin verwendet wird salted_hmacverwendet , um Hash die Sitzungsdaten.
Sberder
Wenn es für Passwort-Hash-Salt verwendet wird, bedeutet das nicht, dass Passwörter in der Datenbank zurückgesetzt werden müssen?
Henning
7
@Henning glaube ich nicht. Die Passwörter werden wie <algorithm>$<iterations>$<salt>$<hash>in auth_user gespeichert , so dass das zufällige Salt jeweils neben dem Passwort gespeichert wird.
Denis Drescher
2
Wäre die Antwort in Django-Versionen> 1.5 signifikant anders? (zB die jetzt aktuelle 1.9)
das-g
36

Seitdem diese Frage gestellt wurde, wurde die Django-Dokumentation geändert und enthält nun eine Antwort.

Der geheime Schlüssel wird verwendet für:

  • Alle Sitzungen, wenn Sie ein anderes Sitzungs-Backend als django.contrib.sessions.backends.cacheoder die Standardeinstellung verwenden get_session_auth_hash().
  • Alle Nachrichten, wenn Sie CookieStorageoder verwenden FallbackStorage.
  • Alle PasswordResetViewToken.
  • Jede Verwendung der kryptografischen Signatur, sofern kein anderer Schlüssel angegeben ist.

Wenn Sie Ihren geheimen Schlüssel drehen, werden alle oben genannten Punkte ungültig. Geheime Schlüssel werden nicht für Kennwörter von Benutzern verwendet, und die Schlüsselrotation wirkt sich nicht auf sie aus.

Mir war nicht genau klar, wie ich den geheimen Schlüssel drehen sollte. Ich fand eine Diskussion darüber, wie Django einen Schlüssel für ein neues Projekt generiert , sowie eine Übersicht, in der andere Optionen besprochen werden . Ich beschloss schließlich, Django dazu zu bringen, ein neues Projekt zu erstellen, den neuen geheimen Schlüssel in mein altes Projekt zu kopieren und dann das neue Projekt zu löschen .

cd ~/junk # Go to some safe directory to create a new project.
django-admin startproject django_scratch
grep SECRET_KEY django_scratch/django_scratch/settings.py # copy to old project
rm -R django_scratch

Aktualisieren

Es sieht so aus, als hätte Django die get_random_secret_key()Funktion in Version 1.10 hinzugefügt . Damit können Sie einen neuen geheimen Schlüssel generieren.

$ ./manage.py shell -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
s!)5@5s79sp=92a+!f4v!1g0d0+64ln3d$xm1f_7=749ht&-zi
$ ./manage.py shell -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
_)+%kymd=f^8o_fea1*yro7atz3w+5(t2/lm2cz70*e$2mn\g3
$
Don Kirkby
quelle
4
Verlässt sich die Generierung geheimer Schlüssel auf den geheimen Schlüssel?
kdazzle
4
Nein, @kdazzle, wenn Sie sich den Quellcodestartproject ansehen , können Sie sehen, dass er mit dem cryptoModul nur eine zufällige Zeichenfolge generiert .
Don Kirkby
12
Heh, sorry, @DonKirkby, schlechter Witz
kdazzle
16

Laut dieser Seite https://docs.djangoproject.com/de/dev/topics/signing/ wird SECRET_KEY hauptsächlich für vorübergehende Daten verwendet - zum Signieren von Daten, die über das Kabel gesendet werden, damit Sie beispielsweise Manipulationen erkennen können. Es sieht so aus, als könnten folgende Dinge kaputt gehen:

  • Signierte Cookies, z. B. Werte vom Typ "Meine Authentifizierung auf diesem Computer speichern". In diesem Fall wird das Cookie ungültig, die Signatur kann nicht überprüft werden und der Benutzer muss sich erneut authentifizieren.
  • Für Benutzer, die Links zum Zurücksetzen des Kennworts oder zum Herunterladen einer benutzerdefinierten Datei angefordert haben, sind diese Links nicht mehr gültig. Die Benutzer müssten diese Links einfach erneut anfordern.

Jemand mit einer neueren und / oder herausragenden Django-Erfahrung als ich mischt sich möglicherweise anders ein, aber ich vermute, dass dies nur eine leichte Unannehmlichkeit für Ihre Benutzer darstellen sollte, wenn Sie nicht explizit etwas mit der Signatur-API tun.

Tim Keating
quelle
6
Warum also nicht bei jedem Neustart des Servers einen neuen Schlüssel generieren?
osa
4
Es würde wahrscheinlich ein Problem verursachen, wenn Sie denselben Server mit mehreren Prozessen ausführen.
dbn
1
@osa Möchten Sie ALLE Benutzer jedes Mal abmelden, wenn Sie Code drücken / Ihren Server neu starten?
EralpB
6

Die SECRET_KEY-Zeichenfolge wird hauptsächlich zum Verschlüsseln und / oder Hashing von Cookie-Daten verwendet. Viele Frameworks (einschließlich Django) kommen dazu, da Standard-Sitzungscookies ihre eigenen Nachteile haben.

Stellen Sie sich vor, Sie haben in Django ein Formular zum Bearbeiten von Artikeln mit einem ausgeblendeten Feld. In diesem ausgeblendeten Feld wird die ID des Artikels gespeichert, den Sie bearbeiten. Und wenn Sie sicher sein möchten, dass Ihnen niemand eine andere Artikel-ID senden kann, fügen Sie ein zusätzliches verstecktes Feld mit der Hash-ID hinzu. Wenn also jemand die ID ändert, wissen Sie es, weil der Hash nicht der gleiche ist.

Natürlich ist dies ein triviales Beispiel, aber so wird SECRET_KEY verwendet.

Django verwendet es intern zum Beispiel für {% csrf_token%} und einige andere Dinge. Es sollte wirklich keine Auswirkungen auf Ihre Anwendung haben, wenn Sie sie aufgrund Ihrer Frage ändern und nicht verwenden.

Die einzige Sache ist , dass vielleicht werden die Sitzungswerte fallen gelassen werden. So müssen sich Benutzer beispielsweise erneut bei admin anmelden, da django keine Sitzung mit einem anderen Schlüssel dekodieren kann.

dunkellos
quelle
1

Ich habe den gleichen Fehler gemacht. Das Standardkennwort war 50 lang, also habe ich Powershell verwendet, um eine 50 lange lange Zeichenfolge zu generieren, und das alte SECRET_KEY durch dieses ersetzt. Ich war angemeldet und nach dem Ersetzen von SECRET_KEY war meine vorherige Sitzung ungültig.

Mit Powershell ( Quelle ):

# Load the .net System.Web namespace which has the GeneratePassword function
[Reflection.Assembly]::LoadWithPartialName("System.Web")

#  GeneratePassword(int length, int numberOfNonAlphanumericCharacters)
[System.Web.Security.Membership]::GeneratePassword(50,5)

Mit Bash ( Quelle ):

# tr includes ABCabc123 and the characters from OWASP's "Password special characters list"
cat /dev/urandom | tr -dc 'A-Za-z0-9!"#$%&\''()*+,-./:;<=>?@[\]^_`{|}~' | head -c 100 ; echo

An diesem Punkt dachte ich mir, warum ich nicht einen größeren Schlüssel probieren sollte, also versuchte ich es mit einem 100 und 1000 langen Schlüssel. Beide haben funktioniert. Wenn ich den Quellcode verstehe , ist das von der Signiererfunktion zurückgegebene Objekt ein hmac-Hash in base64. RFC 2104 hat dies für die erforderliche Länge eines geheimen HMAC-Schlüssels zu sagen.

Anwendungen, die Schlüssel verwenden, die länger als B Bytes sind, hashen den Schlüssel zuerst mit H und verwenden dann die resultierende L-Byte-Zeichenfolge als eigentlichen Schlüssel für HMAC.

Der Schlüssel für HMAC kann beliebig lang sein (Schlüssel, die länger als B Bytes sind, werden zuerst mit H gehasht). Von weniger als L Bytes wird jedoch dringend abgeraten, da dies die Sicherheitsstärke der Funktion verringern würde. Schlüssel, die länger als L Bytes sind, sind akzeptabel, aber die zusätzliche Länge würde die Funktionsstärke nicht wesentlich erhöhen. (Ein längerer Schlüssel kann ratsam sein, wenn die Zufälligkeit des Schlüssels als schwach angesehen wird.)

Um in normales Sprechen zu übersetzen, muss die Größe des geheimen Schlüssels der Größe der Ausgabe entsprechen. Der Schlüssel muss auch in Bits sein. Jede Ziffer in base64 repräsentiert 6 Bits. Wenn Sie also ein 50-stelliges Passwort hätten, hätten Sie einen geheimen 50 x 6 = 300-Bit-Schlüssel. Wenn Sie SHA256 verwenden, benötigen Sie einen 256-Bit-Schlüssel ( sha256 verwendet per Definition 256 Bit ). Ein 50-langes Passwort sollte also funktionieren, es sei denn, Sie planen, einen Hashing-Algorithmus zu verwenden, der größer als SHA256 ist.

Da jedoch zusätzliche Bits im Schlüssel gehasht werden, wird die Leistung durch die Größe des Schlüssels nicht drastisch verringert. Aber es würde Ihnen garantieren, dass Sie genug Bits für größere Hash-Funktionen haben. SHA-512 würde von einem 100 langen SECRET_KEY ( 50 x 6 = 600 Bit> 512 Bit ) abgedeckt .

Rex Linder
quelle