Commit Graph
3 Commits
Author SHA1 Message Date
Claude 2874d79c9e Correctifs de sécurité : XSS stocké, SSRF, force brute, aléa des mots de passe
Audit de l'application. Cinq corrections, la première critique.

XSS stocké non authentifié (critique)
- Le journal d'activité était rendu avec `dangerouslySetInnerHTML` alors qu'il
  agrège des saisies de tiers : titre de promotion d'un adhérent, et surtout nom
  laissé dans le formulaire de contact PUBLIC. N'importe quel visiteur pouvait
  donc faire exécuter du script dans le navigateur d'un administrateur, et
  prendre la main sur son compte.
- Défense aux deux bouts : `sanitizeActivityMessage` ne laisse passer que
  <strong> à l'écriture, et `activityNodes` rend le message en éléments React —
  un message déjà stocké en base ne peut plus rien injecter.

SSRF
- `loadPromoImage` allait chercher toute URL http(s) placée dans le champ image
  d'une promotion, et en poussait le contenu vers Facebook ou LinkedIn : de quoi
  atteindre un service interne ou les métadonnées de l'hébergeur. Seules les
  data-URI sont désormais acceptées, ce qui couvre tous les usages réels.
- Les images sont en plus validées à l'écriture (type et taille), côté promotion
  comme côté profil adhérent.

Authentification
- Aucun frein sur la connexion : blocage progressif après 8 échecs par compte.
- La comparaison bcrypt est menée même sans compte correspondant, sinon le temps
  de réponse révélait quelles adresses existent.

Aléa
- Les mots de passe temporaires venaient de `Math.random()`, prédictible :
  passage à `randomInt` de node:crypto, et longueur portée à 12.

En-têtes
- nosniff, X-Frame-Options, Referrer-Policy, Permissions-Policy et
  frame-ancestors. Une CSP complète demandera des nonces sur les scripts Next.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QXNXRC4j5VLfKvpyyisrnb
2026-07-25 09:02:25 +00:00
MichaelandClaude Opus 4.8 b4d94f2115 Backend: edition image d'entete + logo des adherents
- Champs upload image d'entete (coverUrl) et logo (logoUrl) dans le
  formulaire d'edition d'un adherent (composant ImageField, fichier ->
  data-URL via hidden input)
- updateMember persiste desormais coverUrl + logoUrl, et revalide la
  fiche publique /adherents/[id]
- serverActions.bodySizeLimit a 4mb (les data-URL depassent la limite
  par defaut de 1mb)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 09:47:04 +02:00
Claude 7e22ec50d4 Implémente le site Plein R (Accueil + Backend) sur Next.js + Postgres + Docker
Application unique Next.js (App Router, TypeScript) servant :
- Accueil public : héro, recherche, métiers, promotions, mises à l'honneur
  (données issues de Postgres)
- Backend authentifié avec RBAC : tableau de bord, adhérents (CRUD), modération
  des promotions, administrateurs, espace adhérent (publication avec aperçu)

Technique :
- Drizzle ORM + drizzle-kit (migrations versionnées) sur driver pg
- Auth.js v5 (credentials, sessions JWT), rôles admin/moderator/editor/member
- Middleware de protection de /backend + gardes par rôle dans chaque vue
- Server actions pour toutes les mutations (vérif auth + capacité + revalidate)
- Design fidèle aux maquettes (design-system CSS, animations, responsive)

Conteneurisation :
- 1 conteneur applicatif (sortie standalone) + 1 conteneur Postgres externe
- docker-compose avec healthcheck ; migrations + seed au démarrage
- scripts migrate/seed bundlés (esbuild) pour un runtime sans devDeps

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XwfhYHzC9hQWPDnQ2p53GL
2026-06-26 12:06:21 +00:00