DOCS/status/securite-dette-technique.md
2026-09-03 14:00:51 +02:00

7.0 KiB

3. Sécurité & dette technique

← Section §3 du tableau de bord : STATUS.md

→ Détail complet : security/audit-securite-manager-service.md et security/audit-manager-app.md (audit du 2026-07-13/14)

manager-service — reste à traiter (par priorité)

  • Critique en exposition, différée en calendrier — Secrets committés en clair dans Git (JWT signing key, clés API, connection strings, mot de passe MQTT, token Telegram) → rotation + variables d'environnement + purge historique Git + suppression RELEASE/
    • 📅 Déplacée en fin de backlog le 2026-08-11, à la demande. Motif : les 6 repos sont privés, sur un serveur Gitea auto-hébergé — l'exposition réelle est celle d'un poste de dev, pas d'un dépôt public. La gravité ne change pas, la fenêtre d'urgence oui.
    • ⚠️ Ce que ça déplace dans le plan : la rotation était le verrou L1 du lot A (« ne pas créer la prod avec les clés committées »). Elle reste ce verrou, mais juste avant le lot I au lieu d'ouvrir le lot A. La contrainte à ne pas perdre : elle doit précéder I3 (compose/Traefik prod), sinon la prod naît avec les clés de l'historique et il faut rotationner deux fois.
    • 🔒 Condition de validité : tenable tant que les repos restent privés et qu'aucun collaborateur externe n'est ajouté. Un repo rendu public, un fork, ou un CI tiers qui clone l'historique → la rotation remonte devant immédiatement.
  • HauteEnableSensitiveDataLogging actif en prod ; services Mongo legacy en singleton à corriger ; ValueComparer manquant sur les JSONB ; AssistantService new HttpClient() en boucle corrigé le 2026-08-07 (IHttpClientFactory, 4 occurrences)
  • Moyenne — JWT sans expiration forcée, clés API en clair + comparaison non constant-time, bootstrap PIN sans rate limiting, exceptions internes exposées, backdoor #if DEBUG, double SaveChangesAsync audit (⚠️ vérifier après le fix du 2026-07-15 sur SaveChanges/SaveChangesAsync — peut être partiellement résolu), SectionFactory dupliqué, tests EF InMemory peu représentatifs
  • Basse — conventions REST hétérogènes, PasswordUtils avec RNG non crypto, code mort (MQTT, CORS AllowAll), CORS en dur, ordre middleware

manager-app — reste à traiter (par priorité)

  • Critique — résolu le 2026-08-11. Client généré désynchronisé (manager_api_new/) : 14 fichiers modèle orphelins → flutter analyze inexploitable (183/200 erreurs de bruit, 68 au 09/08). Mesuré après nettoyage : flutter analyze manager_api_new passe de 67 à 3 issues, l'analyse globale de manager-app de 68 erreurs de bruit à 3 erreurs, toutes dans test/widget_test.dart (cassé et connu, voir « Basse » ci-dessous). flutter build web avant comme après — attendu, ces fichiers n'étant dans aucun graphe. flutter analyze redevient un feu vert utilisable, ce qui lève le lien L8
    • Caractérisé précisément le 2026-08-11. lib/api.dart déclare 139 part pour 153 fichiers dans lib/model/. Les 14 restants portent bien part of openapi.api; mais ne sont déclarés part par personne — en Dart, un fichier part non listé par sa bibliothèque est hors du graphe de compilation. D'où l'asymétrie qui a coûté du temps : l'analyzer les lit (il parcourt tout lib/), le compilateur ne les voit jamais. Les supprimer ne peut pas changer un build.
    • Les 14 : agenda_event_stat_dto, app_configuration_link_dto_application_instance, content_dto_resource, content_geo_point, day_stat_dto, game_stat_dto, level_dto, map_dto_map_provider, map_dto_map_type, map_dto_map_type_mapbox, poi_stat_dto, quiz_stat_dto, section_stat_dto, user.
    • Fausse alerte levée le 2026-08-11, à ne pas rouvrir : ContentGeoPoint (un des 14) semble référencé par du code vivant — tablet-app/lib/Screens/Map/marker_view.dart:456 et mymuseum-visitapp/lib/Screens/Sections/Map/marker_view.dart:367, les deux apps dépendant de manager_api_new par path:. Les deux lignes sont dans un bloc commenté (/* ouvert respectivement en 418 et 329) : du code mort, invisible pour le compilateur et pour l'analyzer. Vérifié par comptage de délimiteurs et confirmé par flutter analyze sur les deux fichiers — zéro erreur. Aucun des 14 n'a de référence vivante.
    • 🔒 Les déclencheurs de génération partent avec eux, et pour une autre raison : ce n'est pas du modèle mort, c'est le moyen de régénérer (annotation @Openapi + build_runner). Importés nulle part. Les supprimer ne retire aucun code exécuté — ça verrouille la règle « manager_api_new s'édite à la main » : tant qu'ils sont là, un flutter pub run build_runner build lancé par réflexe régénère le client et écrase les éditions manuelles (onboarding_api.dart, le câblage d'AIApi, le mapping isGoodisCorrect).
    • ⚠️ Ils étaient trois, pas un — trouvé le 2026-08-11. La règle n'était verrouillée que dans manager-app :
      • manager-app/lib/api/openApiTest.dart (dernier run daté du 2026-05-07)
      • mymuseum-visitapp/lib/api/openApiTest.dartle plus dangereux : il génère depuis son propre lib/api/swagger.yaml vers un manager_api_new local, ce qui aurait créé un second client divergent dans un repo qui consomme celui de manager-app par path:. Il portait en plus une des 5 erreurs Dart du repo
      • tablet-app/lib/api/openApi.dart — même configuration (nom de fichier différent, d'où le fait qu'il ait échappé aux recherches précédentes sur openApiTest)
      • plus un résidu tablet-app/manager_api_new/ ne contenant qu'un pubspec.lock, non suivi par git, daté d'avril — une génération avortée Les trois sont supprimés. Contrôle de non-régression du verrou : grep -rl "@Openapi" */lib ne doit renvoyer aucun fichier.
  • Haute — Duplication du shell de dialog (15 occurrences), composants quasi-copiés (translation containers), méthodes build() monolithiques (440-640 lignes), i18n contournée (~100+ strings en dur)
  • Moyenne — Clé AES en dur + IV fixe (chiffrement de session inutile), erreurs API avalées silencieusement (catch (_) {}), _localPath cassé, fichiers morts, TODO visibles à l'écran en prod, dépendances pubspec inutilisées
  • Basse — façades API nullable jamais renullifiées, 58 print() de debug, credentials de test en dur, nommage non conforme Dart, test/widget_test.dart cassé (seul test du projet, ne compile pas)

Prochaine chose à faire si tu as 1h : la rotation des secrets Gitle nettoyage de manager_api_new (Critique manager-app). La rotation des secrets a été déplacée en fin de backlog le 2026-08-11 (repos privés auto-hébergés, cf. ci-dessus) ; le nettoyage du client, lui, est une demi-heure sans risque de build et il rend flutter analyze utilisable pour tout le lot design.