<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>
Aucun commentaire pour le moment. Soyez le premier !