Ce que vous devez savoir sur les tests fuzz et Go

L’utilisation de Aller croît rapidement. C’est désormais le langage préféré pour écrire des logiciels cloud natifs, des logiciels de conteneurs, des outils de ligne de commande, des bases de données, etc. Go a intégré prise en charge des tests depuis pas mal de temps déjà. Cela facilite l’écriture de tests et leur exécution à l’aide de l’outil Go.
Contents
Qu’est-ce que le test fuzz ?
Le fuzzing, parfois aussi appelé fuzz testing, est la pratique consistant à donner une entrée inattendue à votre logiciel. Idéalement, ce test provoque le blocage de votre application ou un comportement inattendu. Indépendamment de ce qui se passe, vous pouvez apprendre beaucoup de la façon dont votre code réagit aux données qu’il n’a pas été programmé pour accepter, et vous pouvez ajouter une gestion des erreurs appropriée.
Tout programme logiciel donné se compose d’instructions qui acceptent des entrées ou des données provenant de diverses sources, puis il traite ces données et génère une sortie appropriée. Au fur et à mesure que le logiciel est développé, une équipe d’ingénieurs de test teste ce logiciel pour trouver des bogues dans le logiciel qui peuvent ensuite être signalés et corrigés. Souvent, l’intention est de voir si le logiciel se comporte comme prévu. Les tests peuvent en outre être divisés en plusieurs domaines, tels que les tests fonctionnels, les tests d’intégration, les tests de performances, etc. Chacun se concentre sur un aspect spécifique de la fonctionnalité du logiciel pour trouver des bogues ou améliorer la fiabilité ou les performances.
Le fuzzing pousse ce processus de test un peu plus loin et essaie de fournir des données “invalides” ou “aléatoires” au logiciel. Ceci est intentionnel et on s’attend à ce que le programme se bloque ou se comporte de manière inattendue pour découvrir des bogues dans le programme afin que les développeurs puissent les corriger. Comme pour les tests, le faire manuellement n’est pas évolutif, c’est pourquoi de nombreux outils de fuzzing ont été écrits pour automatiser ce processus.
Tests logiciels en Go
A titre d’exemple pour tester Add()
fonctionner au sein add.go
, vous pouvez écrire des tests dans add_test.go
en important le package “testing” et en ajoutant la fonctionnalité de test dans une fonction commençant par TestXXX()
.
Étant donné ce code:
func Add(num1, num2 int) int {
}
Dans un fichier nommé add_test.go
, vous pourriez avoir ce code pour tester :
import "testing"func TestAdd(t *testing.T) {
}
Exécutez le test :
$ go test
Ajout de la prise en charge des tests fuzz
L’équipe Go a accepté un proposition d’ajouter le support des tests fuzz à la langue pour poursuivre cet effort. Cela consiste à ajouter un nouveau testing.F
type, l’ajout de FuzzXXX()
fonctions au sein de la _test.go
fichiers, et d’exécuter ces tests avec le -fuzz
L’option est ajoutée à l’outil Go.
Dans un fichier nommé add_test.go
:
func FuzzAdd(f *testing.F) {
}
Exécutez le code :
$ go test -fuzz
Cette la fonctionnalité est expérimentale au moment de la rédaction, mais il devrait être inclus dans la version 1.18. En outre, de nombreuses fonctionnalités telles que -keepfuzzing
et -race
ne sont pas pris en charge pour le moment. L’équipe Go a récemment publié un tuto sur le fuzzing, qui vaut bien une lecture.
Obtenez les dernières fonctionnalités avec l’installation de gotip
Si vous êtes enthousiaste et souhaitez essayer la fonctionnalité avant la sortie officielle, vous pouvez utiliser gotip
, qui vous permet de tester les fonctionnalités Go à venir et de fournir des commentaires. À installer gotip
, vous pouvez utiliser les commandes ci-dessous. Après l’installation, vous pouvez utiliser le gotip
utilitaire pour compiler et exécuter le programme au lieu de l’habituel go
utilitaire.
$ go install golang.org/dl/gotip@latest
$ gotip download$ gotip version
go version devel go1.18-f009910 Thu Jan 6 16:22:21 2022 +0000 linux/amd64
$
Opinions floues dans la communauté
Le fuzzing est souvent un sujet de discussion au sein de la communauté des logiciels, et nous trouvons des gens aux deux extrémités du spectre. Certains considèrent qu’il s’agit d’une technique utile pour trouver des bogues, en particulier sur le front de la sécurité. Alors qu’étant donné les ressources nécessaires (CPU/mémoire) pour le fuzzing, certains le considèrent comme un gâchis ou lui préfèrent d’autres techniques. Cela est même évident dans l’équipe Go. Nous pouvons voir le co-fondateur de Go, Rob Pike, être légèrement sceptique quant aux utilisations du fuzzing et à son implémentation dans Go.
… Bien que le fuzzing soit bon pour trouver certaines classes de bogues, il est très coûteux en CPU et en stockage, et le rapport coût/bénéfice reste incertain. Je crains de gaspiller de l’énergie et de remplir les dépôts git avec du bruit testdata …
Cependant, un autre membre de l’équipe de sécurité Go, Filo Sottile, semble assez optimiste quant à l’ajout du support fuzz à Go, le soutenant également avec quelques exemples et souhaite que cela fasse partie du processus de développement.
J’aime dire que le fuzzing trouve des bogues à la marge. C’est pourquoi nous nous y intéressons en tant qu’équipe de sécurité : les bogues détectés à la marge sont ceux qui n’arrivent pas en production pour devenir des vulnérabilités.
Nous voulons que le fuzzing fasse partie du processus de développement, et non de construction ou de sécurité : apportez une modification au code pertinent…
Fuzzing dans le monde réel
Pour moi, le fuzzing semble assez efficace pour trouver des bogues et rendre les systèmes plus sûrs et résilients. Pour donner un exemple, même le noyau Linux est fuzz testé à l’aide d’un outil appelé Syzkaller, et il a découvert un variété de bogues.
AFL est un autre fuzzer populaire, utilisé pour fuzzer des programmes écrits en C/C++.
Il y avait aussi des options disponibles pour fuzzer les programmes Go dans le passé, l’une d’entre elles étant go-fuzz que Filo mentionne dans ses commentaires GitHub
Les antécédents de go-fuzz fournissent des preuves assez étonnantes que le fuzzing est bon pour trouver des bogues que les humains n’avaient pas trouvés. D’après mon expérience, quelques minutes CPU de fuzzing peuvent être extrêmement efficaces à la marge
Pourquoi ajouter le support natif du fuzzing dans Go
Si l’exigence est de fuzzer les programmes Go et les outils existants comme go-fuzz
pourrait le faire, pourquoi ajouter le support natif du fuzzing au langage ? le Allez brouillonner le brouillon de conception fournit une justification pour le faire. L’idée était de simplifier le processus, car l’utilisation des outils ci-dessus ajoute plus de travail au développeur et comporte de nombreuses fonctionnalités manquantes. Si vous débutez dans le fuzzing, je vous recommande de lire le document de projet de conception.
Les développeurs pourraient utiliser des outils comme go-fuzz ou fzgo (construit sur go-fuzz) pour résoudre certains de leurs besoins. Cependant, chaque solution existante implique plus de travail que les tests Go typiques et manque de fonctionnalités cruciales. Les tests fuzz ne devraient pas être plus compliqués ou moins complets que les autres types de tests Go (comme l’analyse comparative ou les tests unitaires). Les solutions existantes ajoutent des frais généraux supplémentaires, tels que des outils de ligne de commande personnalisés,
Outils Fuzz
Le fuzzing est un ajout bienvenu à la longue liste de fonctionnalités souhaitées du langage Go. Bien qu’expérimental pour le moment, il devrait devenir robuste dans les prochaines versions. Cela donne suffisamment de temps pour l’essayer et explorer ses cas d’utilisation. Plutôt que de le voir comme une surcharge, il doit être considéré comme un outil de test efficace pour découvrir les bogues cachés s’il est utilisé correctement. Les équipes utilisant Go devraient encourager son utilisation, en commençant par les développeurs écrivant de petits tests fuzz et les équipes de test l’étendant davantage pour utiliser pleinement son potentiel.