Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Relire du code pour y repérer les failles

Après cette leçon: Je peux relire un morceau de code avec une liste de contrôle et signaler les lignes à risque.

Leçon de 60 min2 commandesLab d’injection SQL : attaquer une recherche faible, corriger la requête et prouver la correction

Qu'est-ce qu'une revue de code de sécurité ?

Une revue de code de sécurité consiste à relire le code d'un autre, ou le sien, en cherchant ce qui peut mal tourner. On suit une liste de questions plutôt que son intuition.

C'est l'un des moyens les moins chers de trouver une faille, car elle est trouvée avant la mise en ligne. Une relecture de dix minutes évite parfois un incident de dix jours.

À la fin de cette leçon

Remarque

Je peux relire un morceau de code avec une liste de contrôle et signaler les lignes à risque.

Mots-clés

MotCe que ça veut direExemple
Revue de codela relecture du code par une autre personne avant qu'il soit accepté
Liste de contrôleune liste de questions posées à chaque relecture, dans le même ordre
Diffl'affichage des lignes retirées et ajoutées par une modification+ ligne ajoutée
Faux positifune ligne signalée à tort, qui est en réalité sûre
Journall'historique écrit de ce que fait le programme, pour retrouver ce qui s'est passé
Message d'erreurle texte affiché quand quelque chose échoue

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

La règle unique

Attention

Ce laboratoire est une boutique volontairement fragile. Lisez 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 liste de contrôle remplace l'intuition

Sans liste, on regarde ce qui attire l'œil et on oublie le reste. Avec une liste, on pose les mêmes questions à chaque fois, même fatigué.

Chaque question correspond à une leçon de ce module. Pas besoin de tout savoir par cœur : on lit le code ligne par ligne et on coche.

Exemple travaillé : la liste de contrôle

QuestionCe qui doit alerterLeçon
D'où vient la donnée ?Une saisie utilisée sans contrôleValider les données
Comment la requête est-elle écrite ?Un + ou une mise en forme qui colle du texteRequêtes paramétrées
Où sont les secrets ?Un mot de passe ou une clé écrits dans le fichierDépendances et secrets
Comment sont gardés les mots de passe ?Du texte clair, ou un hachage rapide sans selMots de passe et sessions
Que montre une erreur ?Le texte brut de l'erreur de la base ou une traceConception sécurisée
Reste-t-il une trace ?Un journal éteint ou sans dateConception sécurisée

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Deux lignes du laboratoire à relire

Appliquons la liste à la boutique de votre laboratoire. Deux questions suffisent pour commencer : que montre une erreur, et reste-t-il une trace de ce qui se passe ?

Les deux commandes suivantes affichent chacune une ligne du programme, avec son numéro. Elles ne font que lire. Vous jugerez ensuite si chaque ligne passe la liste.

La ligne qui répond en cas d'erreur

Commande
docker exec app grep -n "database error" /tmp/app/app.py

Affiché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.

La ligne qui s'occupe du journal

Commande
docker exec app grep -n "def log_message" /tmp/app/app.py

Affiché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.

Ce que ces deux lignes montrent

La première affiche database error: suivi du texte brut de l'erreur de la base. Un visiteur lit donc des détails sur la construction du site. Un message utile doit rester simple, et le détail doit aller dans un journal.

La seconde est la fonction qui écrit le journal d'accès. Regardez la ligne qui la suit dans le fichier : le programme l'a vidée. Plus rien n'est écrit, donc plus de trace à relire après un incident.

Lire un diff, ligne par ligne

On relit rarement un fichier entier. On relit un diff, c'est-à-dire les lignes retirées, marquées par un moins, et les lignes ajoutées, marquées par un plus.

Posez-vous deux questions sur chaque ligne ajoutée : que reçoit-elle de l'extérieur, et que peut-elle faire d'irréversible ? Une ligne retirée compte aussi : un contrôle supprimé est une porte ouverte.

Un diff à relire avec la liste

Code: python
def chercher(curseur, titre):
-    curseur.execute("SELECT * FROM livres WHERE titre = ?", (titre,))
+    curseur.execute("SELECT * FROM livres WHERE titre = '" + titre + "'")

def lire_cle():
+    cle = "sk_test_ABCDEF123456"
+    return cle

def verifier(utilisateur):
-    if utilisateur.est_admin and utilisateur.session_valide:
+    if utilisateur.session_valide:

Ce que la liste trouve dans ce diff

Trois problèmes. La requête paramétrée a été remplacée par du texte collé avec + : l'injection est de retour. Une clé d'accès a été écrite dans le fichier. Et le contrôle est_admin a été supprimé : n'importe quelle session valable passe.

Le dernier est le plus discret, car la ligne retirée n'apparaît dans aucun fichier final. Seul le diff le montre.

Une erreur fréquente

Attention

Beaucoup pensent qu'une revue cherche des fautes de style. La sécurité regarde autre chose : ce que le code fait de ce qu'il reçoit. Un code bien écrit, bien aligné et bien commenté peut avoir une faille. Une revue de sécurité se fait avec la liste, pas avec le goût.

À propos de ce labo et de sa source: Lab d’injection SQL : attaquer une recherche faible, corriger la requête et prouver la correction

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.