230 votes

Effets de la modification du SECRET_KEY de Django

J'ai fait une erreur et j'ai engagé le fichier de mon projet Django SECRET_KEY dans un dépôt public.

Cette clé aurait dû être gardée secrète selon les docs .

Le projet Django est actif et fonctionne depuis un certain temps avec quelques utilisateurs actifs. Quels sont les effets si je modifie le SECRET_KEY ? Les utilisateurs, cookies, sessions, etc. existants seront-ils affectés ? Évidemment, le nouveau SECRET_KEY ne seront plus stockés dans un lieu public.

235voto

sberder Points 1145

Edit : Cette réponse est basée sur django 1.5

SECRET_KEY est utilisé dans de nombreux endroits différents, je vais d'abord indiquer ce sur quoi il a un impact, puis j'essaierai de passer en revue cette liste et de donner une explication précise de cet impact.

La liste des choses qui utilisent SECRET_KEY directement ou indirectement :

En réalité, la plupart des articles listés ici utilisent SECRET_KEY par le biais de django.utils.crypt.get_random_string() qui l'utilise pour ensemencer le moteur aléatoire. Cela ne sera pas affecté par un changement de la valeur de SECRET_KEY .

L'expérience de l'utilisateur directement impactée par un changement de valeur sont :

  • le décodage des données sera interrompu, ce qui est valable pour tout backend de session (cookies, base de données, fichier ou cache).
  • Le jeton de réinitialisation du mot de passe déjà envoyé ne fonctionnera pas, les utilisateurs devront en demander un nouveau.
  • formulaire de commentaires (si vous utilisez django.contrib.comments ) ne sera pas validé s'il a été demandé avant le changement de valeur et soumis après le changement de valeur. Je pense qu'il s'agit d'un point très mineur mais qui peut être source de confusion pour l'utilisateur.
  • messages (de django.contrib.messages ) ne sera pas validé côté serveur dans les mêmes conditions de temps que pour le formulaire de commentaires.

UPDATE Je travaille maintenant sur django 1.9.5, un regard rapide sur les sources me donne à peu près les mêmes réponses. Je ferai peut-être une inspection approfondie plus tard.

2 votes

Je change SECRET_KEY sur mon serveur de développement local et cela ne me déconnecte pas, il semble donc qu'au moins les sessions(cache) fonctionnent correctement après le changement. Pourriez-vous préciser ce que vous entendez par data decode will break et peut-être indiquer un code (dans django ou un projet d'exemple) qui ne fonctionnera pas ? EDIT : j'utilise toujours django 1.4 - est-ce le cas ?

0 votes

@teferi Je ne sais pas pour la 1.4, il s'agit de jeter un coup d'œil au code. J'ai pointé toutes les sources pour chaque point, tu peux jeter un œil à "protéger les données de session et créer des clés de session aléatoires". C'est normal que vous soyez toujours connecté mais vous ne pourrez pas lire les données contenues dans la session en tant que SECRET_KEY est utilisé dans salted_hmac utilisé pour hacher les données de la session.

0 votes

S'il est utilisé pour le sel de hachage du mot de passe, cela ne signifie-t-il pas que les mots de passe dans la base de données doivent être réinitialisés ?

48voto

Don Kirkby Points 12671

Depuis que cette question a été posée, le Documentation sur Django a été modifié pour inclure une réponse.

La clé secrète est utilisée pour :

  • Toutes les sessions si vous utilisez un autre backend de session que django.contrib.sessions.backends.cache ou vous utilisez l'option par défaut get_session_auth_hash() .
  • Tous les messages si vous utilisez CookieStorage ou FallbackStorage .
  • Tous PasswordResetView jetons.
  • Toute utilisation de la signature cryptographique, sauf si une clé différente est fournie.

Si vous faites tourner votre clé secrète, tout ce qui précède sera invalidé. Les clés secrètes ne sont pas utilisées pour les mots de passe des utilisateurs et la rotation des clés ne les affectera pas.

Je ne savais pas exactement comment je devais faire tourner la clé secrète. J'ai trouvé une discussion sur la façon dont Django génère une clé pour un nouveau projet ainsi qu'un Gist qui aborde les questions suivantes autres options . J'ai finalement décidé que Django devait créer un nouveau projet, copier la nouvelle clé secrète dans mon ancien projet, puis effacer le nouveau projet .

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

Mise à jour

Il semble que Django ait ajouté le get_random_secret_key() fonction dans la version 1.10. Vous pouvez l'utiliser pour générer une nouvelle clé secrète.

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

19voto

Tim Keating Points 2942

Selon cette page https://docs.djangoproject.com/en/dev/topics/signing/ La clé SECRET_KEY est principalement utilisée pour des opérations transitoires, par exemple pour signer des données envoyées par voie électronique afin de détecter toute falsification. Il semble que les choses qui pourraient être cassées sont :

  • Les cookies signés, par exemple les valeurs de type "remember my auth on this computer". Dans ce cas, le cookie sera invalidé, la vérification de la signature échouera et l'utilisateur devra se réauthentifier.
  • Pour tous les utilisateurs qui ont demandé des liens pour une réinitialisation de mot de passe ou un téléchargement de fichier personnalisé, ces liens ne seront plus valides. Les utilisateurs devront simplement demander à nouveau ces liens.

Quelqu'un ayant une expérience de Django plus récente et/ou plus marquante que la mienne peut apporter des précisions, mais je pense qu'à moins que vous ne fassiez explicitement quelque chose avec l'API de signature, cela ne devrait créer qu'un léger inconvénient pour vos utilisateurs.

8 votes

Alors pourquoi ne pas générer une nouvelle clé à chaque redémarrage du serveur ?

4 votes

Cela poserait probablement un problème si vous exécutez le même serveur en utilisant plusieurs processus.

2 votes

@osa voudriez-vous déconnecter TOUS vos utilisateurs à chaque fois que vous poussez du code/redémarrez votre serveur ?

6voto

darkless Points 371

La chaîne SECRET_KEY est principalement utilisée pour chiffrer et/ou hacher les données des cookies. De nombreux frameworks (y compris Django) ont recours à cette méthode car les cookies de session par défaut ont leurs propres inconvénients.

Imaginez que vous avez un formulaire dans django pour éditer des articles avec un champ caché. Dans ce champ caché est stocké l'ID de l'article que vous êtes en train de modifier. Et si vous voulez être sûr que personne ne peut vous envoyer un autre identifiant d'article, vous ajouterez un champ caché supplémentaire avec un identifiant haché. Ainsi, si quelqu'un modifie l'ID, vous le saurez car le hachage ne sera pas le même.

Bien sûr, il s'agit d'un exemple trivial mais c'est ainsi que la SECRET_KEY est utilisée.

Django l'utilise en interne, par exemple pour {% csrf_token %} et quelques autres choses. Cela ne devrait pas avoir d'impact sur votre application si vous le modifiez, compte tenu de votre question et du fait que vous ne l'utilisez pas.

La seule chose est que peut-être les valeurs de la session seront abandonnées. Ainsi, par exemple, les utilisateurs devront se reconnecter à l'administration, car django ne sera pas capable de décoder la session avec une clé différente.

2voto

Rex Linder Points 353

J'ai fait la même erreur. Le mot de passe par défaut était long de 50, j'ai donc utilisé powershell pour générer une chaîne aléatoire longue de 50 et j'ai remplacé l'ancienne SECRET_KEY par celle-ci. J'étais connecté et après avoir remplacé la SECRET_KEY, ma session précédente avait été invalidée.

Avec Powershell ( source ) :

# 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)

Avec Bash ( source ) :

# 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

A ce moment-là, j'ai pensé pourquoi ne pas essayer une clé plus grande, donc j'ai essayé avec une clé de 100 et 1000. Les deux ont fonctionné. Si je comprends bien le code source l'objet retourné par la fonction de signature est un hash hmac en base64. RFC 2104 a ceci à dire sur la longueur requise d'une clé secrète HMAC.

Les applications qui utilisent des clés d'une longueur plus longues que B octets hacheront d'abord la clé avec H et utiliseront ensuite la chaîne chaîne de L octets résultante comme clé réelle pour HMAC.

La clé pour HMAC peut être de n'importe quelle longueur (les clés plus longues que B octets sont sont d'abord hachées à l'aide de H). Cependant, une longueur inférieure à L octets est fortement déconseillé car cela diminuerait la force de sécurité de la fonction fonction. Les clés plus longues que L octets sont acceptables, mais la longueur supplémentaire n'augmente pas de manière significative la force de la fonction. longueur supplémentaire n'augmenterait pas de manière significative la force de la fonction. (A plus longue peut être conseillée si le caractère aléatoire de la clé est considéré comme faible). considéré comme faible).

Pour traduire en langage normal, la taille de la clé secrète doit être de la même taille que la sortie. La clé doit également être en bits. Chaque chiffre en base64 représente 6 bits. Ainsi, si vous avez un mot de passe de 50 caractères, vous aurez une clé secrète de 50 x 6 = 300 bits. Si vous utilisez SHA256, vous aurez besoin d'une clé de 256 bits ( sha256 utilise 256 bits par définition ). Un mot de passe de 50 caractères devrait donc fonctionner, à moins que vous ne prévoyiez d'utiliser un algorithme de hachage plus grand que SHA256.

Mais comme tous les bits supplémentaires de la clé sont hachés, la taille de la clé ne diminuera pas radicalement les performances. Mais cela vous garantirait que vous avez suffisamment de bits pour des fonctions de hachage plus importantes. SHA-512 serait couvert par une clé SECRET_KEY de 100 bits ( 50 x 6 = 600 bits > 512 bits ).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X