xpeditis2.0/audit_security/CORRECTIONS-2026-09-17.md

50 lines
6.7 KiB
Markdown

# Corrections des constats connus — 17 septembre 2026
Branche `check_secu`. Les correctifs et modifications de travail antérieurs sont conservés. Aucun commit, déploiement, paiement, accès à la production ou envoi d'email réel n'a été réalisé.
## SEC-07 — Secrets dans les journaux
Les derniers messages interpolant les tokens transporteur sont supprimés du service et du repository. La vérification d'invitation ne journalise plus le token ; l'exception « réservation introuvable » ne le recopie plus. Les erreurs de livraison SMTP et d'invitation sont remplacées par des erreurs génériques avant leur propagation, pour éviter qu'un appelant journalise un lien ou un mot de passe contenu dans une réponse fournisseur.
Les journaux HTTP utilisent des sérialiseurs à liste de champs autorisés : méthode et modèle de route côté serveur, statut de réponse et erreur générique. Ils n'incluent plus URL réelle, query string, paramètres, headers, cookies, corps ni détails d'erreur du pilote. Le filtre global et l'intercepteur de performance utilisent la même route statique. Pour une route non résolue, le journal indique `[unmatched route]`. Les erreurs HTTP délibérées conservent leur statut et leur message fonctionnel.
La relecture indépendante a identifié un chemin supplémentaire lorsque `DATABASE_LOGGING` est activé : TypeORM affiche ses paramètres SQL directement. Un logger TypeORM dédié enregistre désormais les catégories d'événements sans SQL, valeurs, paramètres ni erreurs brutes. Il est utilisé par l'API et la source de données CLI. Les niveaux de journalisation configurés restent respectés. Ce choix réduit volontairement le détail diagnostic pour empêcher la copie de credentials ; les codes HTTP, événements et références d'erreur restent disponibles.
Tests : sortie réelle Pino contenant des secrets synthétiques en URL, cookies, réponse et erreur ; chemins contrôleur/service/repository ; filtre d'erreur ; logger TypeORM avec logging activé et désactivé. Aucune copie de journaux de production n'est lue. Les anciens secrets déjà présents dans des journaux restent à révoquer lorsque nécessaire ; les copies historiques ne sont pas effacées par le correctif.
## OBS-01 — Erreur de tarif transformée en gratuité
Le comportement est confirmé au niveau du service avec des dépendances simulées. Avant correction, six cas de refus échouaient et cinq tarifs légitimes étaient conservés. Le service ne doit pas interpréter l'impossibilité de déterminer un tarif comme une offre gratuite.
Une erreur de lecture ou un montant invalide produit désormais une erreur HTTP 503 générique. La résolution a lieu avant tout upload en création et avant `booking.accept()` en acceptation. Aucun document ni changement de statut n'est enregistré lorsque le tarif est inconnu. Les valeurs positives et les tarifs explicites zéro/-1 sur mesure conservent leur comportement ; les autres montants négatifs et les valeurs non finies sont refusés.
Treize tests couvrent les échecs avant effets de bord, les montants valides et invalides, ainsi que la création payante en PENDING_PAYMENT et la création sur mesure en PENDING avec notification simulée. Cela démontre le comportement de panne et sa correction ; la capacité d'un attaquant à provoquer cette panne en production n'est pas établie.
## OBS-02 — Destination des webhooks
Aucun correctif de fonctionnement spéculatif n'est appliqué. Deux tests utilisant le véritable `I18nValidationPipe` et les types DTO déclarés par les contrôleurs confirment que création et modification rejettent actuellement une URL non validée avec HTTP 400. Cela ne prouve pas l'absence d'anciens webhooks dangereux dans la base ni d'autres voies d'écriture. Le risque reste documenté avant une future réparation des DTO.
## SEC-19 — Clé d'API littérale en préproduction
Une clé OpenAI était présente dans la modification locale de `docker/stack-portainer-preprod.yaml`. Seule sa valeur a été remplacée par une variable obligatoire `${OPENAI_API_KEY:?OPENAI_API_KEY must be supplied at deployment}` ; les autres modifications de ce fichier sont conservées. Le parsing YAML et l'absence de valeur littérale à cet emplacement sont vérifiés sans afficher la clé et sans charger de fichier `.env`.
**Action externe indispensable : révoquer/remplacer la clé chez le fournisseur et renseigner le secret de déploiement.** Aucune validité ni consommation du compte fournisseur n'est vérifiée. Une clé retirée du fichier peut encore exister dans une copie, une trace ou l'historique de l'outil.
## Autres constats et limites
Les correctifs SEC-01 à SEC-06 et SEC-08 à SEC-18 étaient déjà présents dans Git ou dans les modifications locales, comme indiqué dans le README. Les tests backend correspondants restent inclus dans la suite générale. Aucune nouvelle exécution navigateur/tableur ni revalidation frontend complète n'est revendiquée pour cette passe backend.
Restent hors des corrections locales : rotation SMTP (SEC-10), révocation des anciens liens transporteur/invitation (SEC-05/07), déploiement réel des correctifs et distribution de la CA PostgreSQL (SEC-16). Les scripts secondaires non couverts et l'audit externe des dépendances restent des lacunes de couverture, pas des vulnérabilités déclarées corrigées.
## Vérifications finales et résultats
- `npm test -- --runInBand` depuis apps/backend : **512 tests réussis, 5 ignorés ; 40 suites réussies, 1 ignorée**.
- `npm run build` depuis apps/backend : réussi.
- ESLint ciblé sur les fichiers backend modifiés/ajoutés : réussi.
- Parsing YAML local et contrôle de variable obligatoire OpenAI : réussis, sans interpolation des secrets ni contact fournisseur.
- `git diff --check -- apps/backend` et vérification des liens Markdown : réussis. Le fichier YAML conserve des espaces finaux préexistants à cette passe dans les autres changements utilisateur ; aucune correction globale de ce fichier n'a été effectuée.
Résultats : **fixed** pour les chemins locaux SEC-07, le comportement de panne OBS-01 et le retrait du littéral SEC-19 ; **no_change** pour la voie API de configuration OBS-02, dont le refus est confirmé. Le volet opérationnel de SEC-05/07/10/16/19 reste **blocked** faute d'accès/preuve externe : aucune révocation ni configuration de production n'est revendiquée.
Les tests d'erreur de frais échouaient avant la correction ; ils rejettent maintenant l'opération avant mutation/upload. Les contrôles de création payante et sur mesure passent. Les sorties Pino et TypeORM testées ne contiennent plus les secrets synthétiques alors que les événements, refus et usages légitimes restent observables. Les tests de niveau métier ne remplacent pas une recette de préproduction.