From 91027f3c42b2c4c57cb835f08f59ce8c70a4545e Mon Sep 17 00:00:00 2001 From: hermes-nyora Date: Sun, 23 Aug 2026 17:18:51 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20runbook=20reglement-definitif=20?= =?UTF-8?q?=E2=80=94=20section=20durcissement=20securite=20(token=20rotati?= =?UTF-8?q?on,=20rate=20limit,=20sessions=20HTTPS,=209e=20tool=20MCP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/reglement-definitif-fix-mcp.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/common/reglement-definitif-fix-mcp.md b/common/reglement-definitif-fix-mcp.md index b9321ec..6627720 100644 --- a/common/reglement-definitif-fix-mcp.md +++ b/common/reglement-definitif-fix-mcp.md @@ -3,7 +3,22 @@ **Instance auteur** : hermes-nyora **Date** : 2026-08-23 **Tags** : [infra, mcp, docker, flask, gunicorn, weasyprint, tunisie-telecom, gemini] -**Statut** : valide +**Statut** : valide (durci le 23/08 après-midi — voir section Durcissement en bas) + +--- + +## DURCISSEMENT SÉCURITÉ (23/08/2026 après-midi — exécution Gemini, vérification Hermes) + +Deuxième passage AntiGravity-Gemini sur le même projet (commit 4586d5d@v0) : + +- **Token MCP roté** : `dev-token-please-change` → token 43 chars dans `.env` (chmod 600), plus aucun fallback. Config hermes-tt mise à jour symétriquement. Vérifié : ancien token → 401, nouveau → 200. +- **Comptes** : admin générique désactivé (is_active=0, hash écrasé) ; mot de passe Nabil.Derouiche roté (l'ancien TT@2026! était EN CLAIR dans init_db poussé sur Gitea). Refactor init_db() : création du superadmin uniquement si table vide ET via env ADMIN_USER/ADMIN_INITIAL_PASSWORD. Pas de réécriture d'historique git (rotation rend les valeurs mortes). +- **Rate limiting /login** : 5 req/min/IP fenêtre glissante mémoire, 6e → 429 + Retry-After:60. Piège évité : le healthcheck Docker tapait sur /login toutes les 30s — basculé sur la nouvelle route `/health` (exemptée du limiteur) dans le MÊME déploiement, sinon boucle unhealthy. +- **Sessions** : 8h, HTTPONLY, Samesite Lax, SECURE=True (accès réel via reverse proxy HTTPS reglement-definitif.bolbol.tn — PAS HTTP direct comme supposé initialement). +- **ProxyFix + PREFERRED_URL_SCHEME=https** : le backend Flask voit du HTTP derrière le proxy DSM ; sans ça, redirects en http://. +- **MCP évolutions** : paramètre seuil borné [10-100] sur reglement_consommation + 9e outil reglement_recherche_ligne (recherche textuelle dans Detail_PO, testé réel : query "cable" → résultats avec prix DT formatés). + +Leçon de cadrage : la question SESSION_COOKIE_SECURE posée par l'exécuteur (« HTTP direct ou reverse proxy ? ») a été mal répondue au premier GO (HTTP direct) puis corrigée par Nabil (reverse proxy HTTPS confirmé par test curl 200 sur le domaine). Toujours vérifier soi-même un fait d'infrastructure avant d'en faire une condition de GO. ---