# Checklist sécurité

À cocher avant tout merge sur `develop` ou `main`.

## Authentification

- [ ] Mots de passe hachés en bcrypt (cost ≥ 13) ou argon2id.
- [ ] Pas de mot de passe en clair dans les logs ni dans les exceptions.
- [ ] Rate-limiting actif sur `/login` et `/forgot-password`.
- [ ] Tokens d'invitation et de reset signés et expirables.

## Autorisation

- [ ] Toute action sensible passe par un Voter Symfony (pas de `if (user.role == ...)` dispersé).
- [ ] Le filtre Doctrine `OrganizationFilter` est actif sur tous les controllers métier.
- [ ] Le SUPERADMIN ne peut pas court-circuiter le filtre sans audit log.
- [ ] Les routes `/admin/organizations` (liste/création/suppression), `/admin/rental-platforms`, `/admin/permissions` exigent `ROLE_SUPERADMIN`.
- [ ] L'administration d'une org (edit, membres, comptes, biens) exige le voter `ORG_ADMIN` (profil ADMIN actif sur l'org courante).

## Multi-tenancy

- [ ] Toute nouvelle entité tenant-scoped a une colonne `organization_id` NOT NULL et FK.
- [ ] Toute nouvelle requête a été testée pour vérifier l'isolation entre orgs (au moins 1 test).
- [ ] Aucun cache partagé entre orgs sans clé `organization_id`.

## Entrées utilisateur

- [ ] CSRF actif sur tous les formulaires (par défaut Symfony, sauf API JSON authentifiée).
- [ ] Pas de SQL natif sans paramètres bindés.
- [ ] Validation côté serveur **systématique** (pas de confiance dans le client).
- [ ] Échappement Twig actif (jamais de `|raw` sans justification commentée).

## Fichiers uploadés

- [ ] Validation MIME et taille.
- [ ] Stockage hors webroot (`/uploads/` non servi par nginx).
- [ ] Nom de fichier généré côté serveur (jamais le nom envoyé par l'utilisateur).
- [ ] Pas d'exécution PHP dans le dossier d'uploads (`location ~ \.php$ { deny all; }` dans nginx).

## Secrets et configuration

- [ ] Aucun secret dans le code ni dans les commits (`gitleaks` à brancher en CI).
- [ ] `.env` versionné, `.env.local` jamais.
- [ ] Clés API (futurs connecteurs bancaires) chiffrées avec Symfony Secrets ou KMS.

## Données bancaires

- [ ] IBAN affiché sous forme masquée par défaut (4 derniers chiffres).
- [ ] IBAN complet uniquement à la création/édition par un rôle autorisé.
- [ ] Pas d'IBAN ni de montants détaillés dans les logs ni les exports d'erreurs.
- [ ] Audit log sur toute consultation d'export complet de transactions.

## Headers HTTP

- [ ] `Content-Security-Policy` configuré (nelmio/security-bundle).
- [ ] `Strict-Transport-Security` en prod (HTTPS uniquement).
- [ ] `X-Frame-Options: DENY`.
- [ ] `X-Content-Type-Options: nosniff`.
- [ ] `Referrer-Policy: strict-origin-when-cross-origin`.

## Sessions

- [ ] Cookies de session `httpOnly`, `secure` (en prod), `sameSite=lax`.
- [ ] Régénération de l'ID de session après login.
- [ ] Timeout de session adapté (ex. 8 h d'inactivité, 30 j max).

## Logs et monitoring

- [ ] Audit log alimenté pour : login (succès/échec), changement de rôle, suppression, export, intervention SUPERADMIN.
- [ ] Pas de PII inutile dans les logs applicatifs.
- [ ] Alerting sur les pics d'erreurs 5xx et les tentatives de login massives (futur).

## CI

- [ ] PHPStan niveau cible OK.
- [ ] PHP-CS-Fixer OK.
- [ ] Tests unitaires + intégration verts.
- [ ] Audit `composer audit` sans vuln critique.
- [ ] Scan secrets (`gitleaks`) OK.

## Déploiement

- [ ] `APP_ENV=prod`, `APP_DEBUG=0` en production.
- [ ] Migration jouée avant le rollout.
- [ ] Sauvegarde BDD avant migration destructive.
- [ ] Plan de rollback documenté pour les changements à risque.
