Modèle de sécurité
Modèle de sécurité
La conception de sécurité de Chinaski se décrit simplement : vérifier tout ce que le serveur se fait dire, signer tout ce que le navigateur charge, et ralentir quiconque se comporte mal. Cette page explique les quatre pièces sur lesquelles cela repose : la subresource integrity, la content security policy, la confiance en IP client, et les rate limits/lockouts.
Subresource Integrity (SRI)
Les scripts et feuilles de style auto-hébergés de l'interface admin (le CSS propre de l'UI admin, les polices, l'éditeur, et les scripts de réglages) portent des hash d'intégrité calculés. Quand le navigateur charge un de ces fichiers, il le vérifie contre le hash publié dans la page ; un script falsifié ou échangé est refusé avant de pouvoir s'exécuter.
Détails concrets :
- Les hash sont calculés au démarrage de l'app. Si vous mettez à jour ces fichiers d'assets sur le disque, redémarrez l'application pour que des hash frais soient publiés.
- Si un fichier d'asset était illisible au démarrage, la page charge ce fichier sans l'attribut d'intégrité (avec un avertissement dans le log) plutôt que de casser la page.
Content Security Policy (CSP)
Chaque réponse porte une Content Security Policy stricte :
- Le contenu des pages est verrouillé à l'origine propre du site par défaut ; les scripts et styles en ligne ne s'exécutent que si le serveur les a étiquetés avec un nonce généré à neuf pour cette requête.
- Les soumissions de formulaires sont restreintes à votre propre serveur ; le framing par d'autres sites est bloqué.
- L'intégration d'analytics/bot-check (Cloudflare Turnstile) est le seul point de contact externe autorisé, et disparaît entièrement en mode airgap.
- En plus de la CSP, les réponses portent aussi la protection de frame, la protection contre le sniffing de content-type, une politique de referrer stricte, un HSTS d'un an (le TLS est censé se terminer à votre reverse proxy), et une Permissions-Policy qui désactive les fonctionnalités du navigateur que le CMS n'utilise jamais (caméra, micro, géolocalisation, paiement, USB, et plus).
Deux exceptions délibérées, toutes deux sûres et intentionnelles : les previews de contenu assouplissent la politique parce qu'elles rendent le HTML de votre vrai thème (ces URL requièrent une session admin ou un token de preview secret), et les pages de formulaires publics sont intentionnellement intégrables par d'autres sites ; leurs submissions ne vont toujours que vers votre serveur.
Confiance en IP client (X-Forwarded-For)
Les rate limits, les lockouts de connexion et les logs ont tous besoin de la vraie adresse IP du visiteur. Le CMS la détermine ainsi :
- Si la connexion arrive d'un proxy de confiance (par défaut, uniquement le loopback : la configuration standard où un proxy Caddy ou nginx fait face à internet), le CMS lit les en-têtes transmis et leur fait confiance.
- Si la connexion arrive de n'importe où ailleurs, les en-têtes transmis sont ignorés entièrement et l'adresse réelle de la connexion est utilisée ; voilà pourquoi lier le serveur à une interface publique permettrait à quiconque de défaire vos rate limits.
- Un proxy sur un réseau non loopback (par exemple un bridge Docker) doit être ajouté via le réglage
CHINASKI_TRUSTED_PROXIES(adresses IP ou plages IPv4 séparées par des virgules), pour que les en-têtes transmis soient honorés. Les exemples de proxy livrés utilisent le loopback et n'ont besoin d'aucun réglage.
Rate limits et lockouts
Chinaski limite en débit les surfaces les plus susceptibles d'être abusées, par adresse IP :
| Surface | Limite |
|---|---|
| Connexion admin | Les lockouts escaladent : 1 minute après 5 tentatives échouées, 5 minutes après 10, 30 minutes après 20. Cessez d'essayer pendant environ 10 minutes et le compte se réinitialise. |
| Auto-inscription | 5 tentatives depuis une même IP en rapide succession déclenchent un lockout d'1 heure (et l'inscription elle-même doit d'abord être activée dans les réglages) |
| Récupération de mot de passe | 5 requêtes depuis une même IP déclenchent un lockout d'1 heure |
| Soumissions de formulaires publics | Max 5 par heure par formulaire, et 30 par heure sur tous les formulaires, par IP ; au-delà vous obtenez un HTTP 429 « Too many submissions » |
| API REST | Chaque clé API est limitée par minute (100 requêtes par défaut), comptée atomiquement sur tous les workers du serveur ; les requêtes excédentaires obtiennent un HTTP 429 avec un en-tête Retry-After indiquant quand réessayer |
| URL suspectes | Les sondes de scanners connues (.env, .git/config, wp-login.php, wp-admin, phpmyadmin, et compagnie) sont loguées avec tous les détails de la requête et reçoivent un 404 nu qui ne laisse rien paraître |
Quelques détails à connaître :
- L'activité élevée d'échecs de connexion est écrite dans le journal d'événements, de sorte que les attaques répétées soient remarquées même quand personne ne surveille les logs en direct.
- Le rate limiting des formulaires se base sur la vraie IP client, de sorte qu'il reste exact même quand le CMS omet les IP des visiteurs pour des raisons de confidentialité (signaux Do Not Track / Global Privacy Control, ou un réglage de stockage d'IP par formulaire).
- Au lieu de rejeter catégoriquement, les chemins abusifs peuvent être tarpitted : la réponse est délibérément retardée de quelques secondes. C'est non bloquant ; les visiteurs légitimes ne sont pas affectés pendant que les attaques automatisées perdent du temps.
Ce que tout cela donne
- Le trafic entrant est authentifié par des clés de session que votre serveur signe, jamais par des valeurs fournies par le navigateur seules.
- Tout ce que le navigateur admin charge est vérifié par hash (SRI) et contrôlé par politique (CSP).
- Les frontières de confiance sont explicites : le daemon sait quels réseaux il peut croire et refuse les en-têtes transmis de quiconque d'autre.
- L'abus déclenche de la limitation, du retard ou des lockouts au lieu d'erreurs qui divulguent des informations utiles.
- Chaque tentative échouée et chaque sonde est loguée, de sorte que les incidents sont visibles après coup, dans le journal d'audit, le journal d'événements et les dashboards admin.