Commit Graph
4 Commits
Author SHA1 Message Date
GGThedandClaude Opus 5 9cedf4a038 fix(ops): nginx pointait sur le port du serveur de developpement
STD-06, de l'audit anterieur : "ports et adresses d'ecoute incoherents entre
cinq fichiers". ARCH-007 a unifie les points d'entree Python en vague E/F et
OPS-002 a fait de HOST et PORT des variables en vague H, mais personne n'est
retourne dans app/nginx.conf.

proxy_pass pointait sur 127.0.0.1:5000, qui est le defaut de run.py, le
serveur de developpement. wsgi.py -- ce qui sert reellement la production --
ecoute PORT avec un defaut de 10000. Installer le fichier tel qu'il est
livre donne donc 502 sur chaque page, depuis une configuration qui se lit
comme parfaitement raisonnable et un serveur qui tourne tres bien.

Rien dans le depot ne reliait les deux nombres, donc rien ne pouvait
remarquer qu'ils avaient diverge. Le test est cette relation, ecrite
quelque part qui s'execute. Il couvre aussi les blocs commentes : celui
qu'on decommente dans un an porte le port avec lequel il a ete ecrit.

Le second test garde l'avertissement colle au chemin alias du bloc /static/,
livre avec une valeur devinee et toujours a regler sur le noeud.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-11 19:37:25 -04:00
GGThed d0a9e75fe6 perf: servir les statiques par nginx, et dire ce que le bot n a pas livre
PERF-006. Le bloc location /static/ etait commente : 59 Ko de CSS et de JS
passaient par Waitress a chaque page. L activer tel quel aurait ete une
regression : ces URL ne changent jamais, donc un cache de 30 jours sert une
feuille de style vieille d un mois apres chaque deploiement, sans moyen de
l invalider. url_for('static') estampille maintenant chaque URL du mtime du
fichier ; c est ce qui rend le immutable vrai et pas seulement rapide.

Deux pieges nginx consignes dans le fichier : un add_header dans un location
annule tous les add_header herites du server (nosniff disparaissait du
JavaScript), et un statique manquant doit renvoyer 404 plutot que retomber
sur Flask, sinon un deploiement casse se cache derriere une page qui marche.

PERF-005. Les objets utilisateur Discord sont mis en cache. A etre precis
sur le gain : un envoi coute deux appels reseau, resoudre puis envoyer, et
seul le premier est economise — un premier match a vingt joueurs fait
toujours vingt resolutions. Ce qui est gagne l est entre notifications, la
ou le bot ecrit aux memes personnes soir apres soir.

Chaque message dit desormais ce qu il est devenu, avec le destinataire et
la raison. Les trois echecs ne se ressemblent pas et ne se lisent plus
pareil : une boite fermee est definitive et ne se retente pas, une erreur
HTTP est passagere, un identifiant sans proprietaire est un compte a
corriger. Le lot quotidien annonce son propre deficit.

Piege trouve en ecrivant les tests : configure_logging met propagate=False
sur le logger 'app', et le handler de caplog est sur la racine. Les
assertions sur les journaux passaient seules et echouaient dans la suite
complete, ou une application avait deja ete construite — elles lisaient un
journal vide, pas un bot silencieux.

417 tests.
2026-08-11 11:56:48 -04:00
GGThedandClaude Opus 5 de9448a9aa fix(security,obs): fuite d'erreur sur /health, filtre nl2br, redaction des logs
/health divulguait le message brut du pilote
  L'endpoint n'est pas authentifie et renvoyait f'error: {str(e)}'. Les
  exceptions psycopg contiennent regulierement l'hote, le port, le nom de
  la base et l'utilisateur. Le detail part desormais dans les journaux,
  la reponse ne porte plus qu'un statut.

Filtre nl2br non echappant
  Markup('<br>'.join(...)) marquait le texte comme sur sans l'echapper.
  Le filtre n'etant utilise dans aucun gabarit, la faille etait latente :
  elle se serait ouverte au premier usage. Corrige en Markup('<br>').join(),
  qui echappe chaque segment. Verifie : nl2br('<script>alert(1)</script>')
  rend desormais &lt;script&gt;alert(1)&lt;/script&gt;.

Filtre de redaction des secrets sans effet
  SensitiveDataFilter n'inspectait que record.msg. Or le code journalise
  en style parametre ('...: %s', valeur) : record.msg ne contient que la
  chaine de format, et la donnee sensible vit dans record.args, ignore.
  La redaction ne s'appliquait donc pratiquement jamais. Le record est
  desormais rendu avant filtrage, puis args vide.

Sortie console conditionnee a FLASK_DEBUG
  En production, l'application n'ecrivait rien sur stdout, precisement ou
  regarde la console Pterodactyl. Le handler devient inconditionnel, seul
  son niveau varie.

Journaux du bot Discord perdus
  discord_bot.py utilise getLogger(__name__), soit 'app.discord_bot'.
  Aucun handler n'etait attache a la hierarchie 'app' : les INFO etaient
  jetes et les WARNING+ tombaient sur le handler de dernier recours, sans
  format. Les handlers sont desormais rattaches au logger de paquet.

X-XSS-Protection retire (app.py et nginx.conf)
  En-tete deprecie, l'auditeur vise a ete supprime des navigateurs
  courants et ses dernieres implementations introduisaient elles-memes
  des vulnerabilites.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-07 19:16:37 -04:00
cedrick2711 3feae80767 remodulation du projet et des classes 2026-07-28 23:33:31 -04:00