Penser aux attaques avant d'écrire le code
La conception sécurisée consiste à construire un logiciel de façon qu'une erreur isolée ne le fasse pas tomber. On pense aux attaques avant d'écrire la première ligne.
C'est important, car une faille de conception coûte cher à réparer : il faut parfois reprendre tout le programme. Trois règles simples, bien placées, évitent des semaines de travail.
À la fin de cette leçon
Remarque
Je peux appliquer des règles de conception sécurisée : repérer une frontière de confiance, donner le moindre privilège et refuser par défaut.
Mots-clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Frontière de confiance | la ligne entre ce que le programme contrôle et ce qu'il ne contrôle pas | navigateur / serveur |
| Moindre privilège | donner à chaque compte ou programme seulement les droits dont il a besoin | |
| Refus par défaut | tout est interdit sauf ce qui est permis explicitement | |
| Défaillance sûre | quand quelque chose tombe en panne, le programme choisit le côté fermé | |
| Surface d'attaque | l'ensemble des endroits par où quelqu'un peut essayer d'entrer | |
| Entrée non fiable | toute donnée venue de l'autre côté d'une frontière de confiance |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
La règle unique
Attention
Ce laboratoire est une boutique volontairement fragile. Regardez votre copie privée, et rien d'autre : elle n'a aucune sortie vers Internet. Tester un système qui n'est pas le vôtre, ou sans permission, est un délit dans presque tous les pays.
Une frontière de confiance sépare deux mondes
Un programme reçoit des données de plusieurs endroits. Certains sont sous son contrôle, comme sa propre base. D'autres ne le sont pas, comme ce qu'un visiteur tape.
La ligne entre les deux s'appelle une frontière de confiance. Tout ce qui la franchit vient d'un monde où quelqu'un peut mentir, se tromper ou attaquer. On le vérifie avant de s'en servir.
Exemple travaillé : quatre flux, deux frontières
| Flux | Zone de départ | Zone d'arrivée | Frontière franchie ? |
|---|---|---|---|
| navigateur vers serveur | Internet | Serveur public | Oui : le visiteur est inconnu |
| serveur vers base | Serveur public | Réseau interne | Oui : le serveur peut être attaqué |
| base vers sauvegarde | Réseau interne | Réseau interne | Non : même zone |
| serveur vers un service inconnu | Serveur public | Zone non classée | Oui : une zone inconnue compte comme une frontière |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Le moindre privilège limite les dégâts
Un programme qui n'a besoin que de lire ne doit pas pouvoir écrire. Un compte qui n'a besoin que d'une table ne doit pas voir toute la base.
Si le programme est attaqué, l'attaquant hérite de ses droits, pas de plus. Moins il en a, moins il peut casser. Le moindre privilège ne supprime pas la faille, il réduit ce qu'elle coûte.
Qui fait tourner la boutique du laboratoire ?
La boutique de votre laboratoire ne tourne pas sous un compte tout-puissant. Elle utilise un compte sans droits particuliers. Démarrez le laboratoire, puis lancez cette commande qui regarde seulement.
Elle demande le numéro du compte qui fait tourner le programme. Un numéro élevé, sans nom connu, désigne un compte créé exprès pour un seul usage.
Le numéro du compte du programme
docker exec app id -uAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Exemple travaillé : qui reçoit quels droits
| Compte | A besoin de | Reçoit | Verdict |
|---|---|---|---|
| Le site de la boutique | Lire les produits, écrire les commandes | Lire et écrire dans toute la base | Trop : il peut effacer les comptes |
| Le programme de sauvegarde | Lire la base | Lire la base | Juste ce qu'il faut |
| Le stagiaire du service client | Lire les commandes | Administrer le serveur | Beaucoup trop |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une défaillance sûre refuse dans le doute
Un contrôle peut tomber en panne : le service qui vérifie les droits ne répond plus. Deux choix existent. Laisser passer tout le monde, ou bloquer tout le monde.
La conception sûre bloque. Une porte de secours qui s'ouvre sans clé est utile dans un incendie, mais pas pour protéger une réserve. En cas de doute, la réponse par défaut est non.
Refuser par défaut, en quatre lignes
PERMIS = ["lire_catalogue", "passer_commande"]
# Essayez action = "effacer_base", puis action = "lire_catalogue".
action = "effacer_base"
if action in PERMIS:
print("permis")
else:
print("refusé")
Que répond la boutique à une adresse inconnue ?
La boutique du laboratoire refuse proprement ce qu'elle ne connaît pas. Cette commande demande une page qui n'existe pas, et affiche seulement le code de la réponse.
Le code 404 veut dire « introuvable ». Le programme ne devine pas, ne cherche pas une page proche : il refuse.
Le code de réponse d'une adresse inconnue
curl -s -o /dev/null -w "%{http_code}\n" http://app:8000/inconnuAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
Beaucoup pensent qu'un pare-feu ou un mot de passe à l'entrée suffit : une fois dedans, tout serait permis. C'est faux. Un seul mur qui cède laisse tout ouvert. Plusieurs couches, chacune avec ses propres limites, ralentissent et limitent une attaque.