Paillasse/docs/adr/0004-https-csp-et-exposition.md
Adam Belkacemi 618cd7efbe passe le portail en HTTPS sur syllabuslab.fr, avec en-têtes de sécurité et CSP
Certificat Let's Encrypt obtenu et renouvelé par certbot (authentificateur
nginx), expiration surveillée par Prometheus. TLS selon Mozilla v6.0
intermediate, HSTS, CSP stricte avec nonce sur l'application et adaptée
sur la vitrine, xterm.js servi par le portail. Page de statut prévue sur
status.syllabuslab.fr, administration de Grafana et Kuma par tunnel seul.

Corrige aussi une faille XSS dans la page de classe, la page /cours en
erreur depuis l'étape 8, et NodeSource relancé à chaque déploiement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:39:50 +02:00

3.1 KiB

ADR 0004 — HTTPS, CSP en deux niveaux, et ce qui est exposé sur Internet

  • Date : 2026-10-09
  • Statut : accepté

Contexte

Étape 12 : le portail passe sur syllabuslab.fr en HTTPS. Il faut un certificat qui se renouvelle seul, des en-têtes de sécurité, une CSP « adaptée à xterm.js », Grafana et Uptime Kuma derrière authentification, et une page de statut publique.

Décisions

  1. certbot du dépôt Debian, certonly avec l'authentificateur nginx. Il obtient et renouvelle le certificat sans jamais modifier nos fichiers : Ansible reste seul maître du vhost. Pas d'e-mail ACME (Let's Encrypt n'envoie plus d'avis d'expiration) : c'est Prometheus qui alerte (CertificatExpireBientot, moins de 14 jours).
  2. TLS : Mozilla v6.0 « intermediate » (TLS 1.2 et 1.3, suites ECDHE), pour les vieux postes des établissements. Sans X25519MLKEM768 (OpenSSL 3.0 sur Debian 12) ni OCSP stapling (abandonné par Let's Encrypt). HSTS 2 ans avec includeSubDomains, sans preload (réversible).
  3. CSP en deux niveaux, posée par Laravel (elle dépend de la page) :
    • application (connexion, inscription, toute page authentifiée) : script-src 'self' 'nonce-…'. Les scripts en ligne portent le nonce de la requête ; xterm.js est servi par le portail (Vite) et non plus par jsDelivr ; les gestionnaires onclick/onsubmit sont remplacés par des écouteurs. Une injection de script serait bloquée ;
    • vitrine (pages reprises du design) : scripts en ligne et CDN autorisés. Ces pages contiennent 52 scripts en ligne et le CDN d'exécution de Tailwind ; elles n'affichent aucune donnée d'utilisateur. Les violations sont remontées à /csp-rapport (journal Laravel).
  4. Administration de Grafana et d'Uptime Kuma : tunnel SSH seulement (choix d'Adam). Il faut la clé SSH, puis le mot de passe de l'outil. Rien de plus n'est exposé sur Internet.
  5. Page de statut sur status.syllabuslab.fr : Nginx ne laisse passer que la page de statut, son API en lecture (GET/HEAD) et ses fichiers statiques. Tableau de bord, /socket.io (connexion admin) et /metrics renvoient 404. Le rôle n'active ce site que si le nom résout vers le serveur, et ajoute alors le nom au certificat (--expand).

Alternatives écartées

  • CSP stricte partout : demanderait de réécrire les ~50 pages du design (scripts en ligne, Tailwind par CDN). Reporté (voir docs/dette.md).
  • Grafana et Kuma publics derrière mot de passe : pratique, mais exposés à la force brute pour aucun besoin actuel.
  • certbot en snap (recommandation du projet certbot) : une deuxième chaîne de mises à jour à surveiller ; le paquet Debian suit unattended-upgrades comme le reste.

Conséquences

  • Toute nouvelle page de l'application qui ajoute un script doit lui donner nonce="{{ Vite::cspNonce() }}", sinon le navigateur le bloque (et le signale dans le journal).
  • Permissions-Policy interdit caméra et micro : à ouvrir pour la visio (étape 15).
  • Les tests et scripts doivent passer par https://syllabuslab.fr : le cookie de session est secure.