Optimisez la sécurité, les middlewares et la configuration serveur pour un site robuste.
Avant tout, on définit nos variables sensibles dans un fichier .env
. Strapi lit ces valeurs via env()
:
1# .env2HOST=0.0.0.03PORT=13374APP_KEYS=key1,key2,key35DATABASE_CLIENT=postgres6DATABASE_HOST=db.example.com7DATABASE_PORT=54328DATABASE_NAME=strapi_prod9DATABASE_USERNAME=strapi10DATABASE_PASSWORD=supersecret11DATABASE_SSL=true12DATABASE_URL=postgres://strapi:supersecret@db.example.com:5432/strapi_prod13STRAPI_TOKEN=monTokenPourWebhooks14JWT_SECRET=unAutreSecretTresFort
Ne commite jamais ton .env
dans Git. Utilise Docker secrets ou ton CI/CD pour injecter
ces valeurs en production.
On place dans config/server.ts
la lecture des variables :
1export default ({ env }) => ({2host: env('HOST', '0.0.0.0'),3port: env.int('PORT', 1337),4app: {5keys: env.array('APP_KEYS'), // ^? Clés de chiffrement pour les cookies et JWT6},7webhooks: {8defaultHeaders: {9Authorization: `Bearer ${env('STRAPI_TOKEN')}`, // ^? Protection des webhooks10},11},12});
Dans config/database.ts
, on active SSL pour PostgreSQL/MySQL :
1import path from 'node:path';23export default ({ env }) => {4const client = env('DATABASE_CLIENT', 'sqlite');5const commonSsl = env.bool('DATABASE_SSL', false) && {6rejectUnauthorized: env.bool('DATABASE_SSL_REJECT_UNAUTHORIZED', true),7key: env('DATABASE_SSL_KEY', undefined),8cert: env('DATABASE_SSL_CERT', undefined),9ca: env('DATABASE_SSL_CA', undefined),10};1112const connections = {13postgres: {14connection: {15connectionString: env('DATABASE_URL'),16ssl: commonSsl, // ^? Active SSL si DATABASE_SSL=true17},18pool: { min: 2, max: 10 },19},20// ... autres clients (mysql, sqlite)21};2223return {24connection: { client, ...connections[client] },25};26};
Tester la connexion SSL localement avec psql "sslmode=require ..."
.
On utilise le middleware strapi::security
pour ajouter des headers HTTP via Helmet :
1export default [2'strapi::errors',3{4name: 'strapi::security',5config: {6contentSecurityPolicy: {7directives: {8defaultSrc: ["'self'"], // ^? Limite les sources de scripts9scriptSrc: ["'self'"],10styleSrc: ["'self'", "'unsafe-inline'"],11imgSrc: ["'self'", 'data:'],12connectSrc: ["'self'"],13},14},15hsts: { maxAge: 31536000, includeSubDomains: true },16xssProtection: true,17frameguard: { action: 'deny' },18noSniff: true,19},20},21'strapi::cors',22'strapi::csrf',23'strapi::poweredBy',24'strapi::logger',25'strapi::query',26'strapi::body',27'strapi::favicon',28'strapi::public',29];
// @callout: Utilise strapi::cors
et strapi::csrf
pour bloquer
// toute requête croisée non autorisée.
Configure bien les origines (origin
) dans config/middlewares.ts
si ton front
est sur un domaine différent.
On ajoute un middleware maison ou un plugin pour prévenir les DDoS :
1export default {2enabled: true,3config: {4policy: 'distributed',5points: 100, // 100 requêtes6duration: 60, // par minute7keyPrefix: 'rl:', // préfixe dans Redis (si utilisé)8},9};
Puis on l’injecte dans middlewares.ts
:
1@@2- 'strapi::logger',3+ 'strapi::logger',4+ { name: 'plugin::rate-limit', config: {} },
/admin
) :
1export default ({ env }) => ({2url: env('ADMIN_URL', '/secure-admin'), // ^? URL customisée3auth: {4secret: env('JWT_SECRET'),5},6});
1# Exemple pour Traefik2labels:3- "traefik.http.routers.strapi-secured.rule=Host(`shop.example.com`)"4- "traefik.http.routers.strapi-secured.tls=true"
Garde ton chemin /secure-admin
secret et partage-le uniquement aux admin.
Exemple de fichier docker-compose.yml
:
1version: '3.8'2services:3strapi:4image: strapi/strapi:55env_file: .env6volumes:7- ./build:/srv/app/build8- ./config:/srv/app/config9ports:10- "${PORT}:${PORT}"11depends_on:12- db13db:14image: postgres:1415env_file: .env16volumes:17- db_data:/var/lib/postgresql/data18volumes:19db_data: {}
node_modules
stdout
/stderr
vers un outil de monitoring (ELK, Datadog…)./public/uploads
./health
pour Kubernetes ou ton orchestrateur.env()
dans config/*.ts
.APP_KEYS
/ JWT_SECRET
.config/middlewares.ts
, ajoute un header Referrer-Policy: no-referrer
.config/admin.ts
pour que l’UI soit accessible sur /gestion
.Liens utiles :