Sécurisez vos cookies
Dans settings.py mettez les lignes
SESSION_COOKIE_SECURE = TrueCSRF_COOKIE_SECURE = True
et les cookies ne seront envoyés que via des connexions HTTPS. De plus, vous voulez probablement aussi SESSION_EXPIRE_AT_BROWSER_CLOSE = True
. Notez que si vous utilisez des versions plus anciennes de django (inférieures à 1.4), il n'y a pas de paramètre pour les cookies CSRF sécurisés. En guise de solution rapide, vous pouvez simplement sécuriser le cookie CSRF lorsque le cookie de session est sécurisé ( SESSION_COOKIE_SECURE = True
), en éditant django / middleware / csrf.py
:
classe CsrfViewMiddleware (objet): ... def process_response (self, request, response): ... response.set_cookie (settings.CSRF_COOKIE_NAME, request.META ["CSRF_COOKIE"], max_age = 60 * 60 * 24 * 7 * 52, domain = settings.CSRF_COOKIE_DOMAIN, secure = settings.SESSION_COOKIE_SECURE ou None)
Diriger les requêtes HTTP vers HTTPS dans le serveur Web
Ensuite, vous voulez une règle de réécriture qui redirige les requêtes http vers https, par exemple dans nginx
server {listen 80; réécrire ^ (. *) https: // $ host $ 1 permanent;}
La fonction reverse
de Django et les balises de modèle d'url ne renvoient que des liens relatifs; donc si vous êtes sur une page https, vos liens vous garderont sur le site https.
Définissez la variable d'environnement HTTPS du système d'exploitation sur on
Enfin, (et ma réponse d'origine excluait cela), vous devez activer la variable d'environnement OS HTTPS
sur 'on'
afin que django ajoute https aux liens entièrement générés (par exemple, comme avec HttpRedirectRequest
s ). Si vous utilisez mod_wsgi, vous pouvez ajouter la ligne:
os.environ ['HTTPS'] = "on"
à votre script wsgi. Si vous utilisez uwsgi, vous pouvez ajouter une variable d'environnement par le commutateur de ligne de commande --env HTTPS = on
ou en ajoutant la ligne env = HTTPS = on
à votre uwsgi Fichier .ini
. En dernier recours, si rien d'autre ne fonctionne, vous pouvez modifier votre fichier de paramètres pour avoir les lignes import os
et os.environ ['HTTPS'] = "on"
, qui devrait également fonctionner.
Si vous utilisez wsgi, vous pouvez également définir la variable d'environnement wsgi.url_scheme
sur 'https'
en ajoutant ceci à votre settings.py
:
os.environ ['wsgi.url_scheme'] = 'https'
Le wsgi conseil grâce au commentaire de Vijayendra Bapte.
Vous pouvez voir la nécessité de cette variable d'environnement en lisant django / http / __ init__.py
:
def build_absolute_uri (self, location = None): "" "Construit un URI absolu à partir de l'emplacement et des variables disponibles dans cette requête. Si aucun emplacement n'est spécifié, l'URI absolu est construit sur` `request .get_full_path () ``. "" "sinon location: location = self.get_full_path () sinon absolu_http_url_re.match (location): current_uri = ' % s: //% s% s '% (self.is_secure () et' https 'ou' http ', self.get_host (), self.path) location = urljoin (current_uri, location) return iri_to_uri (location) def is_secure (self): return os.environ.get ("HTTPS") == "on"
Autres éléments du serveur Web:
Prenez celui de ce type conseil et activez les en-têtes HSTS sur votre serveur Web en ajoutant une ligne à nginx:
add_header Strict-Transport-Security max-age = 31536000;
Cela indique à votre navigateur Web que votre site Web pour les 10 prochaines années utilisera uniquement HTTPS. S'il y a une attaque Man-in-the-middle lors d'une prochaine visite à partir du même navigateur (par exemple, vous vous connectez à un routeur malveillant dans un café qui vous redirige vers une version HTTP de la page), votre navigateur se souviendra il est censé être uniquement HTTPS et vous empêche de divulguer vos informations par inadvertance. Mais soyez prudent à ce sujet, vous ne pouvez pas changer d'avis et décider plus tard qu'une partie de votre domaine sera servie via HTTP (jusqu'à ce que les 10 ans se soient écoulés depuis la suppression de cette ligne). Alors planifiez à l'avance; Par exemple, si vous pensez que votre application pourrait bientôt gagner en popularité et que vous devrez être sur un gros CDN qui ne gère pas bien HTTPS à un prix abordable, vous pourriez avoir un problème.
Assurez-vous également de désactiver les protocoles faibles. Soumettez votre domaine à un test SSL pour vérifier les problèmes potentiels (clé trop courte, ne pas utiliser TLSv1.2, utiliser des protocoles défectueux, etc.). Par exemple, dans nginx, j'utilise:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH + ECDSA + AESGCM EECDH + aRSA + AESGCM EECD SHA + ECDH SHA256 EECDH + aRSA + SHA384 EECDH + aRSA + SHA256 EECDH + aRSA + RC4 EECDH EDH + aRSA RC4! ANULL! ENULL! LOW! 3DES! MD5! EXP! PSK! SRP! DSS ";