Skip to Content
SécuritéPartie 1 — Comprendre la sécurité1.3 — Modéliser la menace (STRIDE)

Chapitre 1.3 — Modéliser la menace (STRIDE)

⏱️ TL;DR — Sécuriser « au feeling », c’est colmater des trous au hasard en en laissant d’autres béants. La modélisation de menace (threat modeling) est la méthode qui structure la réflexion : on identifie les actifs (ce qui a de la valeur), on trace les frontières de confiance (où une donnée passe du fiable au non fiable), puis on applique STRIDE — six catégories de menaces (Spoofing, Tampering, Repudiation, Information disclosure, Denial of service, Elevation of privilege) — pour ne rien oublier. Résultat : une liste priorisée de risques et de parades, avant d’écrire le code.

🎯 Objectifs

  • Identifier les actifs d’une appli et leur valeur pour un attaquant.
  • Tracer les frontières de confiance (trust boundaries) sur une architecture.
  • Dérouler la méthode STRIDE pour énumérer les menaces d’un composant.
  • Produire un mini modèle de menace exploitable (menace → parade).

Pourquoi modéliser, plutôt que réagir

Sans méthode, on sécurise ce qu’on connaît (« j’ai lu un article sur le XSS, je pense au XSS ») et on ignore le reste. La modélisation de menace inverse la démarche : au lieu de partir des attaques que tu connais, tu pars de ton système et tu te demandes systématiquement, pour chaque brique, ce qui peut mal tourner. C’est un exercice de conception, léger, qui se fait sur un tableau blanc avant de coder — ou en début de fonctionnalité.

Trois questions structurent tout modèle de menace :

  1. Qu’est-ce qu’on protège ? (les actifs)
  2. Qu’est-ce qui peut mal tourner ? (les menaces)
  3. Qu’est-ce qu’on fait à ce sujet ? (les parades)

Étape 1 — Les actifs et les acteurs

Un actif est quelque chose qui a de la valeur : données personnelles, mots de passe, moyens de paiement, propriété intellectuelle, mais aussi la disponibilité du service ou la réputation. Lister les actifs, c’est savoir ce qu’un attaquant convoite — et donc où concentrer l’effort.

En face, on liste les acteurs : utilisateurs légitimes (aux droits variés), administrateurs, services externes, et bien sûr l’attaquant (externe anonyme, utilisateur authentifié malveillant, insider…). Un bon modèle considère que tout acteur peut être malveillant, y compris un utilisateur connecté.

Étape 2 — Les frontières de confiance

Une frontière de confiance (trust boundary) est l’endroit où une donnée passe d’une zone de confiance à une zone qui ne l’est pas (ou l’inverse). C’est que les contrôles doivent se placer. La frontière la plus importante d’une appli web : entre le navigateur (jamais digne de confiance — l’utilisateur y contrôle tout) et le serveur.

Le principe fondateur : tout ce qui traverse une frontière de confiance depuis une zone non fiable doit être validé et autorisé. Le corps d’une requête, les paramètres, les en-têtes, même un champ « caché » d’un formulaire ou un prix envoyé par le client : côté serveur, tout cela est hostile. La validation faite dans le navigateur (JS) est une aide à l’UX, jamais une sécurité — l’attaquant contourne le front et parle directement à l’API.

⚠️ Piège — Le piège classique du dev front : croire qu’un contrôle fait côté client protège quoi que ce soit. Un champ disabled, une validation JavaScript, un prix calculé dans le navigateur, un rôle stocké dans le localStorage : tout cela est modifiable par l’utilisateur (DevTools, curl, proxy comme Burp). La sécurité vit de l’autre côté de la frontière, sur le serveur. Le client, c’est du confort, pas du contrôle.

Étape 3 — STRIDE : six façons dont ça tourne mal

Une fois les actifs et les frontières posés, STRIDE fournit une checklist de six catégories de menaces. Pour chaque composant ou flux, on passe les six et on se demande « est-ce applicable ici ? ». C’est ce qui évite les angles morts.

LettreMenaceQuestionPropriété CIA violéeParade typique
SSpoofing (usurpation)Peut-on se faire passer pour un autre ?AuthenticitéAuthentification forte, MFA
TTampering (altération)Peut-on modifier données ou code ?IntégritéSignatures, validation, requêtes paramétrées
RRepudiation (répudiation)Peut-on nier avoir fait une action ?TraçabilitéJournalisation fiable, horodatage
IInformation disclosurePeut-on lire ce qui devrait être secret ?ConfidentialitéChiffrement, contrôle d’accès, pas de fuite dans les erreurs
DDenial of servicePeut-on rendre le service indisponible ?DisponibilitéRate limiting, quotas, timeouts
EElevation of privilegePeut-on gagner des droits qu’on n’a pas ?AutorisationAutorisation stricte côté serveur, moindre privilège

Concrètement, appliqué au login de FormaCampus :

  • S — Bruteforce / credential stuffing pour se connecter comme quelqu’un d’autre → parade : hachage lent, rate limiting, MFA.
  • T — Modifier le token de session pour changer d’identité → parade : session signée/opaque côté serveur.
  • R — Un utilisateur nie avoir supprimé un cours → parade : logs d’audit horodatés.
  • I — Le message d’erreur révèle si l’email existe (« mot de passe incorrect » vs « utilisateur inconnu ») → parade : message générique.
  • D — Des milliers de tentatives saturent le service d’auth → parade : rate limiting, captcha après N échecs.
  • E — Un apprenant accède à /admin → parade : autorisation vérifiée côté serveur sur chaque route.

💡 Réflexe — Tu n’as pas besoin d’un document de 40 pages. Un modèle de menace utile tient souvent sur une page : un schéma d’architecture avec les frontières de confiance, et pour chaque composant sensible, une passe STRIDE listant 2-3 menaces réalistes et leur parade. L’important n’est pas la forme, c’est d’avoir systématiquement posé la question « qu’est-ce qui peut mal tourner ici ? ».

Prioriser : tout n’est pas égal

Un modèle de menace liste plus de risques qu’on ne peut en traiter d’un coup. On priorise par le couple impact × probabilité : une élévation de privilège qui expose toutes les données (impact énorme, exploitation facile) passe avant un DoS théorique nécessitant des moyens colossaux. La modélisation ne vise pas le risque zéro (impossible) mais à dépenser l’effort là où il compte.

🧭 Sur FormaCampus — Avant de coder la fonctionnalité « un formateur exporte les résultats de sa classe », on fait une passe STRIDE de dix minutes. Elle révèle vite le risque majeur : Elevation of privilege / Information disclosure — un formateur pourrait-il exporter les résultats d’une autre classe en changeant un classId dans la requête ? (C’est un IDOR, qu’on verra en Partie 5.) La parade est identifiée avant d’écrire la requête : vérifier côté serveur que la classe demandée appartient bien au formateur connecté. Dix minutes de modélisation ont évité une fuite de données.

✏️ Exercices

Exercice 1 — Trace la frontière. Pour une appli Next.js avec des Server Actions qui écrivent en base, où se situe la frontière de confiance principale, et qu’est-ce que ça implique pour les données reçues par une Server Action ?

✅ Solution

La frontière principale est entre le navigateur (non fiable) et le serveur (l’exécution de la Server Action côté serveur). Même si une Server Action ressemble à un simple appel de fonction depuis un composant, elle est en réalité un endpoint réseau : ses arguments arrivent du client et sont donc hostiles. Implication : toute Server Action doit valider ses entrées (par ex. avec un schéma Zod) et vérifier l’autorisation côté serveur, exactement comme une route d’API. Ne jamais supposer que les arguments sont « propres » parce qu’ils viennent de « ton » composant.

Exercice 2 — Passe STRIDE. Applique STRIDE à un endpoint POST /api/avis qui permet à un utilisateur connecté de publier un avis (texte libre) affiché à tous. Donne une menace plausible pour au moins quatre des six lettres.

✅ Solution

Exemple : S (Spoofing) — poster au nom d’un autre si la session est volable → session solide + HttpOnly. T (Tampering) — falsifier l’userId de l’auteur si envoyé par le client → prendre l’auteur depuis la session serveur, pas depuis le corps. I (Information disclosure) — le texte pourrait exfiltrer via un lien piégé ; l’endpoint pourrait fuiter des données d’autres avis → contrôle d’accès + pas de sur-exposition. E (Elevation) — un avis marqué « officiel/modérateur » en trichant sur un champ → ne pas faire confiance aux champs de rôle du client. Et surtout, le texte libre affiché à tous = risque XSS (Tampering de la page des autres) → encodage de sortie / auto-échappement. D — flood d’avis → rate limiting.

🧠 Quiz de révision

1. Quelles sont les trois questions qui structurent un modèle de menace ?

(1) Qu’est-ce qu’on protège ? (les actifs), (2) Qu’est-ce qui peut mal tourner ? (les menaces), (3) Qu’est-ce qu’on fait ? (les parades). On part du système, pas des attaques qu’on connaît déjà.

2. Qu’est-ce qu’une frontière de confiance, et quelle est la principale d’une appli web ?

L’endroit où une donnée passe d’une zone de confiance à une zone qui ne l’est pas (ou inversement) — c’est que se placent les contrôles. La principale : entre le navigateur (jamais fiable) et le serveur. Tout ce qui la traverse depuis le client est hostile.

3. Développe l’acronyme STRIDE.

Spoofing (usurpation), Tampering (altération), Repudiation (répudiation), Information disclosure (divulgation), Denial of service (déni de service), Elevation of privilege (élévation de privilège). Six catégories de menaces à passer en revue par composant.

4. Pourquoi la validation côté client n’est-elle pas une sécurité ?

Parce que le client est entièrement sous le contrôle de l’utilisateur : il peut modifier le JS, désactiver les validations, ou parler directement à l’API avec curl/un proxy. La validation front sert l’UX ; la sécurité doit être (re)faite côté serveur, de l’autre côté de la frontière de confiance.

5. Comment priorise-t-on les menaces identifiées ?

Par impact × probabilité : on traite d’abord les menaces à fort impact et exploitation facile (ex. élévation de privilège exposant toutes les données), avant les risques théoriques peu probables. Le but n’est pas le risque zéro mais de mettre l’effort là où il compte.


Chapitre suivant : OWASP & l’état d’esprit — la boussole de la sécurité web et la bascule mentale « attaquant / défenseur ».

Last updated on