Thème
02 — Évaluation des risques de cybersécurité
Ce document présente l'évaluation des risques exigée par l'annexe VII et démontre la couverture des exigences essentielles de l'annexe I.
1. Méthode
Pour chaque exigence essentielle : état de la mesure technique, puis, le cas échéant, risque résiduel tracé avec sa justification. Un risque explicitement tracé et justifié est un risque accepté ; un risque implicite ne l'est pas.
Chaque mesure est rattachée au code qui la met en œuvre (§3) : un constat non traçable à un fichier du dépôt n'a pas sa place ici, et une évolution du code peut le rendre caduc.
2. Couverture des exigences essentielles (annexe I)
| Exigence (annexe I) | Mesure | État |
|---|---|---|
| Configuration sécurisée par défaut | Secret imposé au démarrage (aucun défaut public), aucune identité de la base ne conserve de mot de passe par défaut (superutilisateur du cluster inclus), compte anonyme absent, réglages durcis à l'installation | Conforme |
| Protection des accès (auth / RBAC / limitation de débit) | JWT, BCrypt, refresh tokens hachés, rôles, anti-force brute, durée de session bornée ; aucun point d'entrée réseau ne teste un mot de passe sans identifiant | Conforme |
| Confidentialité en transit | HTTPS/TLS sur Kestrel + hub SignalR, redirection, HSTS, cookies Secure | Conforme |
| Confidentialité au repos | DPAPI pour la clé JWT et le secret applicatif ; InisConfigCrypto explicitement documenté comme obfuscation | Conforme avec risque résiduel (§4) |
| Intégrité (code / mises à jour) | Signature Authenticode horodatée des binaires et de l'installateur ; -RequireSigning refuse de produire un livrable non signé | Conforme (sous réserve de disposer d'un certificat de signature) |
| Minimisation des données | Peu de données personnelles ; les profils publics n'exposent aucune empreinte | Conforme avec risque résiduel (A4, §4) |
| Réduction de la surface d'attaque | Pare-feu profil privé, CORS LAN, en-têtes de durcissement, CSP, PostgreSQL local, téléversements typés d'après leur contenu, vérification du mot de passe administrateur restreinte au poste | Conforme |
| Journalisation / surveillance | Serilog (90 j) + audit métier en base + journal réglementaire inaltérable, conservation plancher 5 ans | Conforme |
| Mises à jour de sécurité | Catégorie Security au CHANGELOG, installateur signé | Conforme (voir 06) |
| Nomenclature logicielle (SBOM) | CycloneDX (.NET + npm) en intégration continue | Conforme |
| Traitement des vulnérabilités | Scan CI (Dependabot, npm audit, dotnet list --vulnerable) + processus | Conforme (voir 05) |
| Tests de sécurité réguliers | Scan de dépendances en CI + revue de sécurité par version majeure | Partiel — à poursuivre |
| Divulgation coordonnée + point de contact | ../SECURITY.md + security.txt | Conforme |
| Distribution sécurisée des mises à jour | Signature de code + vérification à l'installation | Conforme |
3. Où les mesures sont mises en œuvre
Rattachement au code, pour vérification.
| Mesure | Emplacement |
|---|---|
| Refus de démarrer sans secret configuré, aucun secret par défaut | SecurityDefaults.Resolve, appelé par StartupExtensions.BuildConnectionString |
| Secret unique du poste (SuperAdmin, rôle applicatif, superutilisateur du cluster) | deployment/provision-postgres.ps1, provision-admin-secret.ps1 |
| Authentification JWT, hachage BCrypt, jetons de rafraîchissement hachés en base | Application/Services/AuthService.cs |
Durée de session bornée (30 jours par défaut, Auth:RefreshTokenDays) | AuthService.RefreshTokenDays |
| Temporisation par compte après échecs répétés, en plus de la limite par adresse | ILoginThrottle |
| Réarmement réservé au SuperAdmin, autres commandes ouvertes aux opérateurs | PanelsController.ExecuteCommand, ModbusController.SendCommand |
| Vérification du mot de passe administrateur restreinte à la boucle locale | AuthController.IsLoopbackRequest |
HTTPS, redirection, HSTS, cookies Secure | StartupExtensions.ConfigureKestrel ; certificat par deployment/provision-https-cert.ps1 |
| Secrets scellés au repos (DPAPI, portée machine) | Configuration/CryptoConfigProtector.cs, JwtKeyProvider |
| Journal réglementaire inaltérable, conservation plancher 5 ans | AuditTrailService, AuditTrailRetentionService ; purges refusées par SystemLogsController |
| Téléversements typés d'après leur contenu | UsersController.DetectImageMediaType (avatars), MapsController (plans) |
| Signature Authenticode horodatée, refus d'un livrable non signé | deployment/build-all.ps1 (Invoke-CodeSign, -RequireSigning) |
4. Risques résiduels acceptés
Ces choix sont défendables mais doivent rester tracés dans l'évaluation des risques.
4.1 Secrets partagés au repos
- Constat. Le mot de passe SuperAdmin (
Security:SuperAdminPassword) est saisi par l'installateur lors de la première installation et n'est jamais livré dans l'installateur. Il gouverne les trois identités du poste : compte SuperAdmin, rôle applicatif PostgreSQL et superutilisateur du cluster embarqué. L'exploitant n'a donc qu'une valeur à conserver, et conserve un accès direct à sa base sur toute la vie de l'installation. Ce secret est chiffré au repos via DPAPI au premier démarrage du service (appsettings.Crypto.prod.protected) et le fichier en clair est supprimé. Les clés revendeur sont fournies dans le paquet d'installation, puis scellées au repos par le même mécanisme. - Risques résiduels. (a) Le mot de passe SuperAdmin transite en clair pendant la fenêtre de saisie et jusqu'au premier démarrage, avant scellement. (b) DPAPI en portée machine est déchiffrable par un administrateur local du poste. (c) Les clés revendeur sont un secret partagé entre installations et doivent donc être fournies dans le paquet, ce qui exclut par nature une confidentialité absolue.
- Justification. Déploiement sur poste dédié, en réseau local fermé, sous contrôle physique et administratif du site. Une application hors ligne qui démarre en service ne peut garantir la confidentialité d'un secret face à un administrateur local ; DPAPI constitue une protection à l'état de l'art proportionnée à ce contexte.
- Mesure compensatoire. Saisie du mot de passe SuperAdmin par l'installateur (aucun défaut, aucun secret livré dans l'installateur), DPAPI (portée machine), suppression du fichier en clair après protection, mot de passe PostgreSQL jamais journalisé. Aucun binaire livré ne porte de mot de passe de base : le service reprend celui de sa propre chaîne de connexion lorsqu'il doit réaligner le rôle applicatif.
- Corollaire assumé. Le secret et les données forment un couple : la désinstallation les préserve ou les supprime ensemble. Un secret changé alors que la base est conservée laisse le superutilisateur sur l'ancienne valeur et empêche le réalignement automatique du rôle — cas signalé à l'exploitant plutôt que contourné par une valeur de secours connue.
4.2 Obfuscation des configurations INIS (InisConfigCrypto)
- Constat.
InisConfigCryptoapplique une obfuscation XOR (sans sel, IV ni MAC). - Décision. Ce mécanisme sert l'interopérabilité avec les configurations INIS, pas la confidentialité. Il ne protège aucune donnée sensible au sens du CRA et n'est pas présenté comme du chiffrement.
4.3 Certificat TLS auto-signé
- Constat. À défaut de certificat fourni (
Https:CertificatePath), un certificat auto-signé (CN=localhost) est approvisionné à l'installation et installé dans le magasin racine du poste, ou généré en mémoire en repli. - Risque résiduel. L'accès LAN par adresse IP depuis un autre poste peut déclencher un avertissement de certificat (nom/confiance). Le chiffrement du transport est néanmoins assuré.
- Mesure compensatoire. Possibilité d'approvisionner un certificat d'organisation via
Https:CertificatePath.
4.4 Commandes courantes ouvertes aux opérateurs (A2)
- Constat.
POST /api/panels/{id}/commandporte les commandes courantes (silence, mise hors/en service, essai), accessibles aux rôles authentifiés. La commande de réarmement (reset) est, elle, réservée au SuperAdmin (contrôle appliqué côté service, pas seulement masqué dans l'interface). - Décision. Ouverture assumée des commandes courantes aux opérateurs, cohérente avec l'exploitation d'un poste de supervision incendie ; le réarmement, action à conséquence, reste réservé au SuperAdmin. Journalisation des commandes en audit pour l'imputabilité.
4.5 Exposition des profils (A4)
- Constat.
GET /api/auth/profiles(anonyme) expose les noms, rôles et avatars des comptes, sans empreinte de mot de passe. - Décision. Énumération de comptes assumée pour l'ergonomie de l'écran de connexion sur poste dédié, en réseau fermé.
- Mesure associée. La liste des comptes privilégiés ne peut plus servir de levier : la vérification d'un mot de passe sans identifiant, qui confrontait chaque essai à l'ensemble de ces comptes, n'est atteignable que depuis le poste. Les tentatives d'authentification restent limitées par adresse et temporisées par compte après échecs répétés.
4.6 Lien Modbus en clair (limite protocolaire)
- Constat. Modbus TCP/RTU n'offre ni chiffrement ni authentification applicative (nature du protocole).
- Décision. Limite protocolaire assumée. Mesures compensatoires : segmentation réseau du lien Modbus, contrôle physique, journalisation des écritures de commande. Exigences portées au fabricant du firmware et compensations côté Superviseur : 07 — Exigences fournisseur firmware.
5. Pistes ouvertes
Améliorations identifiées, non engagées.
- Durée de session. 30 jours par défaut sur un poste fonctionnant en continu ; à raccourcir si l'exploitation le permet (
Auth:RefreshTokenDays). - Certificat TLS approuvé par les postes tiers. Élargir le SAN du certificat auto-signé au nom d'hôte et aux adresses du serveur puis distribuer sa racine aux appareils du parc, ou fournir un certificat issu d'une autorité interne via
Https:CertificatePath. - Hôtes autorisés.
AllowedHostsaccepte tout hôte ; à restreindre à ceux réellement servis. - Journalisation. Durcir les droits du répertoire de journaux, et envisager un export vers un collecteur externe.
- Tests de sécurité. Au-delà de l'analyse des dépendances et du SAST en intégration continue, une revue de sécurité par version majeure reste à planifier.
- Authentification à plusieurs facteurs. Absente ; à évaluer au regard du contexte d'exploitation (poste dédié, réseau fermé).
6. Réserves et limites
- Ce document n'est pas un avis juridique. La classification et les obligations exactes doivent être confirmées avec un conseil compétent avant toute déclaration (00, 04).
- Le firmware des centrales n'est pas sous notre contrôle. Nous pouvons proposer des exigences à son fabricant et compenser côté Superviseur, pas garantir sa conformité.
- Certaines faiblesses sont des décisions produit assumées (§4.4, §4.5, §4.6). Elles restent défendables, mais doivent rester tracées ici plutôt que laissées implicites.
- Cet état reflète le code au moment de sa rédaction. Chaque mesure est traçable à un fichier du dépôt (§3) ; toute évolution ultérieure peut modifier ces constats.