Ce document détaille toutes les mesures de sécurité implémentées dans ReContent.dev pour un déploiement production sécurisé.
Date de dernière mise à jour : 2025-10-23 Version : 1.0.0
Avant :
app.use(cors()); // ❌ Toutes origines autoriséesAprès :
// ✅ Whitelist stricte basée sur l'environnement
const allowedOrigins = isProduction
? ['https://recontent.devamalix.fr', 'https://www.recontent.devamalix.fr']
: ['http://localhost:8090', 'http://localhost:5173'];Fichier : api/config/cors.js
Protection contre :
- Abus de l'API
- DDoS simples
- Épuisement du quota Mistral AI
Limites configurées :
- Général : 200 requêtes / 15 minutes par IP
- Génération de contenu : 100 requêtes / 15 minutes par IP
- Authentification (futur) : 5 tentatives / heure
Fichier : api/config/rateLimiter.js
Validations implémentées :
- ✅ Longueur du contenu : 100 - 10,000 caractères
- ✅ Whitelist des plateformes :
['twitter', 'linkedin', 'devto', 'github', 'newsletter'] - ✅ Whitelist des tons :
['casual', 'professional', 'technical'] - ✅ Limites sur les champs de profil (nom max 100 chars, bio max 500 chars)
- ✅ Validation du type et format des données
Fichier : api/middleware/validator.js
Remplace : 11 console.log() par un logger structuré
Niveaux de log :
- Production : Warn et Error uniquement
- Développement : Debug, Info, Warn, Error
Rotation des logs :
- Fichiers logs :
logs/error.logetlogs/combined.log - Taille maximale : 5MB par fichier
- Conservation : 5 fichiers maximum
Fichier : api/config/logger.js
API - Avant :
image: node:20-alpine
command: sh -c "npm install && npm start" # ❌ Root, réinstallation à chaque démarrageAPI - Après :
# ✅ Multi-stage, npm ci, USER node, dumb-init
FROM node:20-alpine AS dependencies
RUN npm ci --only=production
FROM node:20-alpine AS production
USER nodejs # Non-root
CMD ["node", "index.js"]Fichiers :
Protection contre :
- Inclusion de
node_modulesdans les images - Exposition de fichiers
.envdans les images - Copie de fichiers
.gitet logs
Fichiers :
Avant :
ports:
- "3002:3002" # ❌ API accessible directementAprès :
# ✅ Port commenté, uniquement accessible via Traefik
# ports:
# - "3002:3002"Fichier : docker-compose.yml
Internet
│
└─> Traefik (HTTPS uniquement)
│
├─> Frontend (recontent.devamalix.fr)
│ └─> Nginx (headers de sécurité)
│
└─> API (recontent.devamalix.fr/api)
├─> CORS whitelist
├─> Rate limiting
├─> Input validation
└─> Winston logging
Fichier .env (à créer sur le serveur) :
MISTRAL_API_KEY=your_actual_mistral_api_key_here
API_PORT=3002
NODE_ENV=production
TZ=Europe/Paris.envdans .gitignore.env.exampleavec placeholders uniquement- Variables chargées via
dotenvdans api/index.js - Validation au démarrage : api/index.js
Frontend :
- "traefik.http.routers.recontent-frontend.rule=Host(`recontent.devamalix.fr`)"
- "traefik.http.routers.recontent-frontend.entrypoints=websecure"
- "traefik.http.routers.recontent-frontend.tls.certresolver=letsencrypt"API :
- "traefik.http.routers.recontent-api.rule=Host(`recontent.devamalix.fr`) && PathPrefix(`/api`)"
- "traefik.http.middlewares.recontent-api-stripprefix.stripprefix.prefixes=/api"Headers de sécurité automatiques via Traefik :
X-Frame-Options: DENYX-Content-Type-Options: nosniffX-XSS-Protection: 1; mode=blockStrict-Transport-Security: max-age=31536000; includeSubDomains; preload
Fichier : docker-compose.yml
# Test depuis origine non autorisée (doit échouer)
curl -H "Origin: https://evil.com" \
-H "Access-Control-Request-Method: POST" \
-X OPTIONS \
https://recontent.devamalix.fr/api/generate
# Test depuis origine autorisée (doit réussir)
curl -H "Origin: https://recontent.devamalix.fr" \
-H "Access-Control-Request-Method: POST" \
-X OPTIONS \
https://recontent.devamalix.fr/api/generate# Envoyer 101 requêtes rapidement (la 101ème doit échouer avec 429)
for i in {1..101}; do
curl https://recontent.devamalix.fr/api/health
done# Test avec contenu trop court (doit échouer)
curl -X POST https://recontent.devamalix.fr/api/generate \
-H "Content-Type: application/json" \
-d '{"content":"test","platforms":["twitter"]}'
# Test avec plateforme invalide (doit échouer)
curl -X POST https://recontent.devamalix.fr/api/generate \
-H "Content-Type: application/json" \
-d '{"content":"...contenu valide...","platforms":["facebook"]}'# Doit échouer (connexion refusée)
curl http://recontent.devamalix.fr:3002/healthEmplacement : api/logs/
error.log- Erreurs uniquementcombined.log- Warn + Error
Accès aux logs en production :
# Logs temps réel
docker logs -f nexus-recontent-api
# Logs archivés
docker exec nexus-recontent-api cat /app/logs/combined.log- Taux d'erreur 4xx/5xx
- Nombre de requêtes bloquées par rate limiting
- Temps de réponse de Mistral API
- Violations CORS
- Créer le fichier
.envsur le VPS avec la vraie clé Mistral - Vérifier que le réseau
traefik-networkexiste - Configurer le DNS :
recontent.devamalix.fr→ IP du VPS - Tester en local avec
docker-compose.dev.yml
# Sur le VPS
cd /path/to/recontent
# 1. Créer .env
cp .env.example .env
nano .env # Ajouter la vraie clé Mistral
# 2. Build des images
docker-compose build
# 3. Démarrer les services
docker-compose up -d
# 4. Vérifier les logs
docker-compose logs -f
# 5. Tester les endpoints
curl https://recontent.devamalix.fr/api/health
curl https://recontent.devamalix.fr/- Vérifier le certificat HTTPS (Let's Encrypt)
- Tester CORS depuis le frontend
- Vérifier rate limiting
- Tester la génération de contenu
- Configurer Watchtower pour mises à jour automatiques
- Configurer monitoring (Uptime Robot, etc.)
dotenv: 16.6.1 → 17.2.3 ✅
API :
{
"express": "^4.18.2",
"axios": "^1.6.2",
"cors": "^2.8.5",
"dotenv": "^17.2.3",
"winston": "^3.18.3",
"express-rate-limit": "^8.1.0"
}Frontend :
{
"react": "^19.1.1",
"axios": "^1.12.2",
"react-router-dom": "^7.9.3"
}# Vérifier les vulnérabilités
cd api && npm audit
cd frontend && npm audit
# Mettre à jour les dépendances
npm updateSi vous découvrez une vulnérabilité de sécurité, NE PAS créer d'issue publique.
Informations à fournir :
- Description de la vulnérabilité
- Étapes pour reproduire
- Impact potentiel
- Suggestion de correction (si possible)
Délai de réponse : 48 heures
- OWASP Top 10
- Docker Security Best Practices
- Express.js Security Best Practices
- Node.js Security Checklist
Ce projet est sous licence MIT. Voir LICENSE pour plus de détails.
Dernière révision : 2025-10-23 Auteur : Matthieu Alix Projet : ReContent.dev v1.0.0