Securite Web

Securiser Django en Production : Guide 2026

Securiser Django en Production : Guide 2026
Auteur MEME
Date 25 mars 2026
Lecture 2 min
Vues 22

<h2>Introduction</h2>
<p>Déployer une application Django en production expose immédiatement votre système à des tentatives d'intrusion, des attaques par force brute, des injections SQL et des exploits Zero Day. Dans cet article, nous couvrons les pratiques avancées de sécurisation basées sur une expérience réelle de déploiement sur VPS avec Docker, Nginx et Gunicorn.</p>

<h2>1. Configuration de base : settings.py en production</h2>
<p>La première ligne de défense commence dans votre fichier de configuration :</p>
<pre><code class="language-python">DEBUG = False
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')</code></pre>
<p>Ne jamais stocker votre SECRET_KEY en dur dans le code. Utilisez des variables d'environnement via un fichier .env chargé avec python-dotenv.</p>

<h2>2. Middleware de pare-feu personnalisé</h2>
<p>Django permet d'intercepter chaque requête avant qu'elle n'atteigne vos vues. Voici un pare-feu applicatif sur mesure :</p>
<pre><code class="language-python">class ErgyFirewallMiddleware:
WHITELIST_PREFIXES = ('/static/', '/media/', '/sitemap.xml', '/robots.txt')
WHITELIST_IPS = ('127.0.0.1',)

def __call__(self, request):
for prefix in self.WHITELIST_PREFIXES:
if request.path.startswith(prefix):
return self.get_response(request)
ip = self.get_client_ip(request)
if ip in self.WHITELIST_IPS:
return self.get_response(request)
if self.is_malicious(request):
return self.render_403(request)
return self.get_response(request)

def is_malicious(self, request):
patterns = ['../', 'select ', 'drop table', '/etc/passwd', 'cmd.exe']
target = (request.path + request.META.get('QUERY_STRING', '')).lower()
return any(p in target for p in patterns)</code></pre>
<p>Ce middleware doit être placé en deuxième position dans MIDDLEWARE, juste après SecurityMiddleware.</p>

<h2>3. Authentification à deux facteurs (2FA TOTP)</h2>
<p>La 2FA via TOTP est indispensable pour les comptes administrateurs. Avec pyotp :</p>
<pre><code class="language-python">import pyotp

class UserProfile(models.Model):
totp_secret = models.CharField(max_length=32, blank=True)
totp_enabled = models.BooleanField(default=False)

def verify_totp(self, token):
if not self.totp_secret:
return False
return pyotp.TOTP(self.totp_secret).verify(token, valid_window=1)

def get_qr_uri(self):
return pyotp.TOTP(self.totp_secret).provisioning_uri(
name=self.user.email,
issuer_name="ErgyCodePy"
)</code></pre>

<h2>4. Rotation automatique des clés sensibles</h2>
<p>Une pratique DevSecOps avancée : faire tourner automatiquement les mots de passe en production via un thread daemon :</p>
<pre><code class="language-python">import threading, secrets

class PasswordRotator:
def __init__(self):
self.interval = settings.ROTATION_INTERVAL

def start(self):
if settings.ROTATE_DB_PASSWORD:
self._schedule()

def _schedule(self):
t = threading.Timer(self.interval, self._rotate)
t.daemon = True
t.start()

def _rotate(self):
new_pwd = secrets.token_urlsafe(32)
self._update_db_password(new_pwd)
self._schedule()</code></pre>

<h2>5. Headers de sécurité Nginx</h2>
<pre><code class="language-nginx">add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self';" always;</code></pre>

<h2>6. PostgreSQL isolé dans Docker</h2>
<p>La base de données ne doit jamais exposer de port vers l'extérieur :</p>
<pre><code class="language-yaml">services:
db:
image: postgres:15
# NE JAMAIS exposer le port en production
# ports: - "5432:5432"
networks:
- internal_network

networks:
internal_network:
internal: true</code></pre>

<h2>7. Audit Django natif</h2>
<p>Django intègre un outil de vérification. Lancez-le avant chaque déploiement :</p>
<pre><code class="language-bash">python manage.py check --deploy</code></pre>
<p>En production, vous devez obtenir : System check identified no issues (0 silenced).</p>

<h2>Conclusion</h2>
<p>La sécurisation d'une application Django en production est un processus continu. Les techniques présentées sont issues d'une implémentation réelle sur ErgyCodePy, déployé sur VPS avec Docker, Nginx et Gunicorn. Auditez régulièrement votre stack, gardez vos dépendances à jour et surveillez vos logs de sécurité.</p>

Connectez-vous pour participer à la discussion.

Se connecter

0 Commentaires

Aucun commentaire pour le moment. Soyez le premier !

Voir tous les articles