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

35 lines
7.0 KiB
Markdown

# 3. Sécurité & dette technique
> ← Section **§3** du tableau de bord : [STATUS.md](../STATUS.md)
→ Détail complet : **[security/audit-securite-manager-service.md](../security/audit-securite-manager-service.md)** et **[security/audit-manager-app.md](../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.
- [ ] **Haute**`EnableSensitiveDataLogging` 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é)
- [x]**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 `isGood``isCorrect`).
- ⚠️ **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.dart`**le 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 Git~~**le 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.
---