Threat modeling d'une plateforme avec STRIDE
Objectifs pédagogiques¶
- Comprendre pourquoi modéliser les menaces d'une plateforme et pas seulement d'une application
- Cartographier une plateforme avec un diagramme de flux de données et ses frontières de confiance
- Identifier les menaces avec la méthode STRIDE
- Coter et prioriser les risques dans un registre
- Relier chaque risque à un contrôle automatisé et à une preuve vérifiable
- Justifier les Quality Gates et la matrice de conformité PSSI à partir du registre
Pourquoi modéliser les menaces¶
Une plateforme, pas seulement une application¶
Une API sécurisée ne suffit pas si la chaîne qui la construit et l'exécute est vulnérable
- Code source : dépôts, branches, droits de merge
- Pipeline CI : runners, variables, jetons, images d'outillage
- Registre : images, tags, signatures
- Dépôt GitOps : état désiré de la production
- Cluster : API Kubernetes, nœuds, RBAC, réseau
- Secrets : clés de paiement, jetons, certificats
- Humains : accès d'administration, astreinte, prestataires
Les quatre questions du threat modeling¶
Le Threat Modeling Manifesto résume la démarche en quatre questions
- Sur quoi travaillons-nous ? Cartographier le système
- Qu'est-ce qui peut mal tourner ? Identifier les menaces
- Qu'allons-nous faire ? Choisir les contrôles
- Avons-nous fait du bon travail ? Vérifier, prouver, réviser
Pas besoin d'un outil complexe : un schéma, un tableau et une équipe qui se pose les bonnes questions
Quand modéliser¶
- À la conception, avant d'écrire le premier manifest
- À chaque changement d'architecture : nouveau composant, nouvelle dépendance, nouveau flux
- Après un incident ou un postmortem
- Avant un audit, pour vérifier que chaque risque a son contrôle
- Régulièrement, pour intégrer les menaces émergentes
Le modèle est un document vivant, versionné avec le code
Cartographier : DFD & frontières de confiance¶
Les éléments d'un DFD¶
Un Data Flow Diagram décrit comment les données circulent
- Entité externe : acteur hors de votre contrôle (client, développeur, prestataire de paiement)
- Processus : composant qui traite la donnée (API, job CI, ArgoCD)
- Stockage : endroit où la donnée repose (registre, dépôt Git, base, Secret)
- Flux : échange de données entre deux éléments
- Frontière de confiance : ligne que franchit un flux en changeant de niveau de privilège
Les menaces se concentrent sur les flux qui traversent une frontière
DFD simplifié d'une API de paiement¶
[Développeur] --push--> (GitLab : dépôt applicatif)
|
===== frontière : CI ========== v =================================
(Pipeline CI) --image--> [[Registre]]
| |
MR de promotion |
v |
[[Dépôt GitOps]] |
===== frontière : cluster ===== | ==================== | ==========
(ArgoCD) --manifests--> (API Kubernetes)
|
(Pod API de paiement) <--pull--+
| ^
===== frontière : Internet ============== | ====== | ==============
[Prestataire de paiement] [Client]
Les frontières de confiance de la plateforme¶
- Poste développeur → forge Git : qui peut pousser, avec quelle authentification
- Pipeline → registre : qui peut publier ou écraser une image
- Pipeline → dépôt GitOps : qui peut modifier l'état de la production
- ArgoCD → API Kubernetes : quels droits pour l'opérateur de déploiement
- Pod → API Kubernetes : que peut faire un conteneur compromis
- Cluster → Internet : quels flux sortants sont réellement nécessaires
- Internet → Ingress : quelle surface est exposée aux clients
STRIDE¶
STRIDE en un coup d'œil¶
| Lettre | Menace | Propriété violée |
|---|---|---|
| S | Spoofing : usurpation d'identité | Authenticité |
| T | Tampering : altération | Intégrité |
| R | Repudiation : répudiation | Non-répudiation |
| I | Information disclosure : divulgation | Confidentialité |
| D | Denial of service : déni de service | Disponibilité |
| E | Elevation of privilege : élévation de privilèges | Autorisation |
On passe chaque élément et chaque flux du DFD au crible des six catégories
S - Spoofing : usurpation d'identité¶
Exemples sur la plateforme
- Un jeton CI volé sert à publier une image au nom de la pipeline
- Une image au nom proche d'une image officielle est tirée par erreur (typosquatting)
- Le jeton de ServiceAccount monté dans un pod est réutilisé par un attaquant
- Un faux webhook de prestataire de paiement est envoyé à l'API
Contrôles associés
- Identités fédérées OIDC et MFA, jetons de courte durée
- Signature des images et vérification de l'identité du signataire à l'admission
automountServiceAccountToken: falsequand le pod n'appelle pas l'API Kubernetes
T - Tampering : altération¶
Exemples sur la plateforme
- Un tag d'image est réécrit après les scans de sécurité
- Une dépendance ou une image d'outillage est compromise en amont
- Un administrateur modifie la production à la main avec
kubectl - Un artefact est modifié entre deux jobs de la pipeline
Contrôles associés
- Référence des images par digest, signature et attestation
- Épinglage des versions d'outils, SBOM et analyse de composition
- GitOps avec réconciliation automatique de la dérive
- Branches protégées et merge uniquement par Merge Request
R - Repudiation : répudiation¶
Exemples sur la plateforme
- Un déploiement manuel en production ne laisse aucune trace exploitable
- Un changement de configuration est impossible à attribuer
- Les journaux d'audit de l'API Kubernetes ou de la machine sont désactivés
- Une preuve de test n'est ni datée ni conservée
Contrôles associés
- Tout changement de production passe par un commit revu dans le dépôt GitOps
- Journaux d'audit Kubernetes et
auditdsur les machines - Signatures consignées dans un journal de transparence
- Preuves horodatées et versionnées
I - Information disclosure : divulgation¶
Exemples sur la plateforme
- Une clé du prestataire de paiement est codée en dur dans le code
- Un Secret Kubernetes encodé en base64 est committé dans le dépôt GitOps
- Les logs contiennent des jetons ou des données de carte
- L'API divulgue sa technologie via ses en-têtes HTTP
Contrôles associés
- Détection de secrets bloquante, rotation immédiate en cas de fuite
- Secrets chiffrés dans Git (Sealed Secrets, SOPS) ou gestionnaire de secrets
- Masquage des variables CI et filtrage des logs
- En-têtes de sécurité vérifiés par un scan DAST
D - Denial of service : déni de service¶
Exemples sur la plateforme
- Un pic de trafic sature l'unique instance de l'API
- Un pod sans limites consomme toutes les ressources du nœud
- La perte d'un nœud emporte le seul réplica d'un composant critique
- Un composant partagé comme le DNS devient un point de défaillance unique
Contrôles associés
- Requests, limits, HPA et PodDisruptionBudget
- Plusieurs réplicas répartis sur plusieurs nœuds
- Tests de stress et expériences de chaos pour prouver la tenue
- Limitation de débit à l'entrée de la plateforme
E - Elevation of privilege : élévation de privilèges¶
Exemples sur la plateforme
- Un conteneur exécuté en root sert de tremplin vers le nœud
- Un pod privilégié ou monté sur le socket Docker prend le contrôle de l'hôte
- Un ServiceAccount dispose de droits
cluster-admininutiles - Un compte de la machine dispose de
sudosans mot de passe
Contrôles associés
- Pod Security Admission en
restrictedet politiques d'admission - RBAC au moindre privilège, revu régulièrement
- Durcissement des machines selon un benchmark reconnu
- Build d'images sans démon ni privilèges
Du risque à la preuve¶
Coter un risque : vraisemblance × impact¶
| Note | Vraisemblance | Impact |
|---|---|---|
| 1 | Improbable | Négligeable |
| 2 | Possible | Limité |
| 3 | Probable | Important |
| 4 | Quasi certain | Critique (fraude, fuite, arrêt) |
Criticité = vraisemblance × impact
- 12 à 16 : critique, contrôle bloquant obligatoire
- 8 et 9 : élevé, contrôle requis avant la mise en production
- 4 à 6 : modéré, contrôle planifié
- 1 à 3 : faible, risque accepté et documenté
Traiter un risque¶
- Réduire : mettre en place un contrôle qui diminue la vraisemblance ou l'impact
- Éviter : supprimer la fonctionnalité ou le flux à l'origine du risque
- Transférer : confier le risque à un tiers (assurance, prestataire certifié)
- Accepter : décision explicite, validée et datée, avec une revue programmée
Après traitement, il reste toujours un risque résiduel : il doit être coté et assumé
La chaîne risque → contrôle → preuve¶
Chaque ligne du registre doit pouvoir être suivie de bout en bout
- Risque : menace STRIDE, actif concerné, criticité
- Contrôle : mesure qui traite le risque, automatisée dès que possible
- Preuve : artefact horodaté qui démontre que le contrôle fonctionne
Un contrôle sans risque est du bruit, un risque critique sans contrôle est un angle mort, un contrôle sans preuve est une promesse
Exemple de registre : API de paiement¶
| ID | Menace | V×I | Contrôle | Preuve |
|---|---|---|---|---|
| R1 | I : clé de paiement dans Git | 16 | Détection de secrets bloquante, rotation, secret chiffré | Pipeline en échec sur une MR piégée |
| R2 | T : image altérée après les scans | 12 | Promotion par digest, signature, vérification à l'admission | Refus d'une image non signée |
| R3 | E : conteneur root exploité | 8 | PSA restricted, politiques d'admission | Refus d'un pod root |
| R4 | D : saturation lors d'un pic | 9 | HPA, PDB, test de stress | Rapport de charge et capture du scale-out |
| R5 | R : changement de prod non tracé | 9 | GitOps, branches protégées, réconciliation | Historique des MR et dérive corrigée |
Du registre aux Quality Gates¶
Chaque job bloquant de la pipeline référence le risque qu'il traite
secrets:gitleaks: # R1 - divulgation de secrets
stage: lint
script:
- gitleaks git --redact .
trivy:image: # R2, R6 - image altérée ou vulnérable
stage: scan
script:
- trivy image --exit-code 1 --severity CRITICAL "$IMAGE@$IMAGE_DIGEST"
Le seuil de blocage découle de la criticité du risque, pas des réglages par défaut de l'outil
Lien avec la PSSI¶
- La PSSI fixe les exigences de l'organisation
- Le registre des risques les traduit en menaces concrètes sur la plateforme
- La matrice de conformité relie chaque exigence à un contrôle, un outil, une preuve et un statut
- Les dérogations sont justifiées, validées, compensées et revues
- L'audit vérifie la chaîne, pas seulement la présence des outils
Faire vivre le modèle¶
- Versionner le registre dans le dépôt (
docs/risques.md) et le faire évoluer par Merge Request - Revoir le modèle à chaque changement d'architecture et après chaque incident
- Intégrer les constats des audits et des expériences de chaos
- Suivre les menaces émergentes : compromission de la supply chain, vol de jetons CI, chemins d'attaque dans le cluster
- Mesurer : part des risques critiques couverts par un contrôle automatisé et prouvé
Outillage¶
- OWASP Threat Dragon : dessin de DFD et génération de menaces STRIDE, open source
- OWASP pytm : modèle de menaces décrit en Python, versionnable et rejouable
- Un simple fichier Markdown : souvent suffisant pour démarrer, l'essentiel est la discipline de revue
L'outil compte moins que la régularité de l'exercice et la traçabilité jusqu'à la preuve
À retenir¶
- On modélise la plateforme entière : code, pipeline, registre, GitOps, cluster, secrets
- Les menaces se concentrent sur les flux qui franchissent une frontière de confiance
- STRIDE passe chaque élément au crible de six propriétés de sécurité
- Le registre cote, priorise et trace chaque risque jusqu'à un contrôle et une preuve
- Les Quality Gates et la matrice de conformité PSSI découlent du registre
Pour aller plus loin¶
- Threat Modeling Manifesto : https://www.threatmodelingmanifesto.org/
- OWASP Threat Dragon : https://owasp.org/www-project-threat-dragon/
- Introduction au DevSecOps : https://bastienmaurice.fr/slides/devsecops/from-devops-to-devsecops/00-introduction-au-devsecops/
- Quality Gate : https://bastienmaurice.fr/cicd/integration-continue/quality-gate/