# Corrections après audit — 10 octobre 2026

## Livré dans le code

- Clé de session locale persistante, privée et ignorée par Git ; clé obligatoire en production. Cookies Secure en production, HttpOnly et SameSite=Lax ; rotation du CSRF après connexion/changement de mot de passe.
- Limitation partagée en base : 20 essais par compte et 100 par IP / tranche de 15 minutes, réponse 429. Compteurs incluant les réussites, identifiants/IP hachés avec clé ; échecs journalisés sans identifiant sensible. Vérification de hash factice pour comptes inconnus.
- Déconnexion POST avec CSRF, formulaires mis à jour.
- CSP avec nonce pour scripts inline, Bootstrap 5.3.3 servi localement, filtres sans gestionnaire inline ; anti-cadrage, nosniff, Referrer-Policy et HSTS production. Polices Google encore externes.
- Contrôle réel des images PNG/JPEG (décodage et plafond 25 Mpx), PDF parsés (100 pages maximum, sans chiffrement, formulaire, annotation, action automatique ou pièces embarquées). Rejet des fichiers non conformes. Quotas par collaborateur : 100 fichiers / seuil 100 Mio. Le plafond global de requête reste 10 Mio. Ces contrôles ne remplacent pas un antivirus.
- Verrou par salarié pour création/décision de demande, week-end et ajustement de soldes ; seconde validation refusée et auto-approbation interdite à tous les rôles.
- Contrôles NaN/Inf, durée week-end 0–24 h, jour/type cohérents, doublons week-end actifs refusés, montants de paie bornés. Demandes limitées à 366 jours par saisie pour éviter les calculs sans borne ; longues absences à découper.
- Unicité SQL insensible à la casse des identifiants et NIC non vides ; conflits renvoyés en 409. L’initialisation refuse les doublons déjà présents : aucune suppression automatique.
- PostgreSQL : comparaisons booléennes portables, paramètres booléens, valeurs DATE/TIMESTAMP normalisées en ISO, NUMERIC adapté au contrat flottant existant, IDs INSERT RETURNING, champs de coordonnées élargis. Les calculs de paie restent une estimation en flottants : comptabilité définitive et arrondis à valider.
- Statistiques recalculées en jours ouvrables et fraction de journée, périodes coupées à la frontière d’année ; requêtes SQL spécifiques SQLite retirées des écrans actifs. Ce n’est toujours pas un taux d’absentéisme rapporté au temps théorique.
- Mois dynamiques et heure de Maurice ; initialisation explicite `RH_ENV=production python app.py init-db`, plus de migration au chargement Passenger. Démarrage production refuse secrets/base/dossier privé manquants et schéma absent.
- Migration SQLite → PostgreSQL réécrite : source en lecture seule, cible métier vide, colonnes complètes ou refus, transaction unique, aucune commande TRUNCATE, comparaison du nombre de lignes. Les tables de référence semées à l’initialisation sont remplacées dans la transaction. Les séquences PostgreSQL peuvent avancer même si une transaction échoue ; cela crée seulement des trous d’IDs.
- Erreurs de journal d’audit désormais signalées sans secret ; l’action métier déjà validée ne sera pas annulée si le journal échoue. Une politique d’archivage inviolable reste à définir.
- Dépendances Python verrouillées pour livraison ; Pillow 12.3.0 et pypdf 6.20.0 inclus.

## Vérifications réalisées

18 contrôles ciblés initiaux repassés, puis 9 tests de régression réussis dans `tests/test_security.py`, sur base SQLite temporaire fictive : pages admin/employé, CSRF/déconnexion, double validation concurrente avec débit unique, auto-approbation, limite d’essais, PNG/PDF/faux PDF, durée infinie et en-têtes. Pas de modification des salariés réels. OSV : aucune alerte retournée pour les 13 versions Python contrôlées le 10/10/2026.

Commande : `.venv\Scripts\python.exe -m unittest discover -s tests -v`.

## Conditions restant à lever avant production

1. Exécuter initialisation et tests complets sur le PostgreSQL du client : aucun moteur PostgreSQL disponible localement. La compatibilité corrigée n’a pas encore été validée sur une base réelle.
2. Confirmer nom de domaine, IP, FTPS certifié, racine privée et configuration Python/cPanel ; aucun transfert effectué.
3. Vérifier proxy de confiance, HTTPS, droits fichiers, sauvegarde et restauration. Ne pas activer RH_PROXY_HOPS sans confirmation hébergeur.
4. Confirmer qui voit la paie (hr/admin/payroll_admin actuels) et les justificatifs médicaux (propriétaire + responsables habilités). Aucun changement silencieux de cette politique métier.
5. Définir rétention/suppression des justificatifs et audit, antivirus si exigé, 2FA administrateur, supervision et alertes. Limites anti-bruteforce par tranches fixes ne remplacent pas une protection hébergeur contre les attaques distribuées.
6. Validation RH/juridique des règles de congés, calendrier France/Maurice et barèmes astreinte. Clôture de paie et comptabilité finale non ajoutées dans ce lot.
7. Vérifier le rendu dans un navigateur et l’installation PWA sur iOS/Android sous HTTPS ; tests HTTP ne valident pas le comportement visuel/JavaScript.

Les constats de l’audit initial sont conservés pour traçabilité ; ce document indique les corrections et limites actuelles.

Vérification complémentaire dans le navigateur local : connexion avec compte fictif, chargement du formulaire, sélection maladie et apparition du justificatif réussis ; aucune erreur/warning JavaScript relevée dans les logs consultés. Capture privée : instance/audit-formulaire-verifie.png. Aucun formulaire de demande envoyé. Installation mobile et rendu multi-écrans restent à vérifier sur le domaine.
