Commit Graph
4 Commits
Author SHA1 Message Date
GGThedandClaude Opus 5 7cec18c139 style: formater le depot avec ruff format
QUA-002, premiere moitie. **Ce commit ne fait que reformater** : aucun
changement de comportement, aucune ligne de logique touchee. 72 fichiers,
4 restaient deja conformes. Il est isole exprès, pour que `git log -p` sur
les commits voisins reste lisible.

`quote-style = "preserve"` etait deja pose dans pyproject.toml, ce qui
evite le brassage guillemets simples / doubles : le diff porte sur les
retours a la ligne, l indentation des appels longs et les virgules
finales, pas sur le style de chaine.

Verification : 263 tests passent avant et apres, ruff check propre.

L activation en CI arrive dans le commit suivant, separement, pour que ce
diff-ci ne contienne rien d autre.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-08 15:53:10 -04:00
GGThedandClaude Opus 5 ab44258d72 feat(obs): journaliser les evenements d'authentification
OBS-001. logging_config.py configurait un fichier auth.log avec rotation,
un logger nomme 'team_tryouts.auth' et un filtre de redaction. Mais
get_auth_logger n'etait importe nulle part : le fichier etait cree et
restait vide. Aucune connexion, aucun echec, aucun verrouillage, aucun
changement de role, aucune suppression de compte ne laissait de trace.
En cas de suspicion de compromission, il n'y avait rien a consulter.

Ajout de log_auth_event(event, **fields), qui emet des paires cle=valeur
ordonnees -- greppable sans dependance de journalisation JSON.

Evenements couverts
  authentification  login.success, login.failure,
                    login.failure.unknown_user, login.rejected.locked,
                    login.rejected.deactivated, account.locked, logout,
                    account.registered
  administration    account.created_by_admin, account.updated,
                    account.role_changed (avec ancien et nouveau role),
                    account.deleted, account.password_reset_by_admin
  libre-service     account.password_changed

Le champ ip vient de request.remote_addr, donc de X-Forwarded-For. Tant que
Waitress tourne avec trusted_proxy='*' (SEC-WEB-002), cette valeur est
choisie par l'appelant : c'est une indication, pas une preuve. Le point est
documente dans la docstring.

Un test a fait remonter ARCH-003, jusqu'ici classe comme fragilite latente
  Journaliser en fin de edit_user levait DetachedInstanceError : le
  changement de role appelle db.session.remove() en plein cycle de requete,
  ce qui detache current_user de la session. Le code s'en tirait parce qu'il
  redirigeait immediatement sans plus y toucher. L'identite de l'acteur est
  desormais capturee en debut de traitement. Le constat est donc confirme
  comme reel, et non plus seulement probable -- sa correction de fond reste
  au programme.

15 tests, dont 4 sur le filtre de redaction lui-meme : c'est un controle de
securite, il doit etre verifie.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-07 20:01:24 -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