google/oss-fuzz-gen : générer des fuzz targets avec un LLM, puis les noter contre OSS-Fuzz
LLM powered fuzzing via OSS-Fuzz.
En bref
- De quoi s’agit-il ?
- Le dépôt décrit un cadre qui fait écrire des harnais de fuzzing par un modèle de langage, les compile et les mesure face aux cibles écrites à la main dans OSS-Fuzz. L'intérêt tient moins à la génération qu'à la chaîne d'évaluation qui l'entoure, et c'est aussi là que se trouvent ses contraintes.
- À qui s’adresse-t-il ?
- À adopter si vous maintenez déjà un projet intégré à OSS-Fuzz, si vous disposez d'un accès Vertex AI ou d'une clé OpenAI, et si votre objectif est de mesurer la couverture d'une cible générée par rapport à une cible humaine existante. À éviter si vous cherchez un scanner prêt à l'emploi sur un binaire que vous ne pouvez pas compiler, ou si vous n'avez pas de budget d'inférence à consacrer à des expériences dont le résultat peut être nul.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- L’activité ralentit. Les derniers commits datent d’il y a 6 mois.
- En quel langage est-il écrit ?
- Principalement Python, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème n'est pas de trouver des bugs, c'est d'écrire le harnais
Écrire un fuzz target correct pour une bibliothèque C ou C++ demande de connaître son API, ses invariants d'entrée et la manière dont OSS-Fuzz compile le projet. C'est un travail lent, souvent repoussé, et une cible mal écrite produit du bruit plutôt que des plantages exploitables. Le dépôt part de ce constat et propose de laisser un modèle de langage produire une première version du harnais, puis de la juger automatiquement. Le public visé est donc précis : des mainteneurs dont le projet est déjà pris en charge par OSS-Fuzz, ou des équipes de sécurité qui veulent savoir si un LLM fait mieux qu'une cible humaine sur un code donné. Le README ne présente pas d'installation type bibliothèque ni de commande d'usage rapide, seulement un renvoi vers USAGE.md. C'est un cadre expérimental, pas un outil packagé.
Le trajet d'une cible générée, du prompt au verdict chiffré
Le mécanisme se lit dans la structure du dépôt plus que dans le README. Un prompt builder assemble le contexte du projet à partir d'un template, les templates visibles étant rangés sous prompts/template_xml. Le modèle choisi produit le code du harnais. Ce code est ensuite compilé et exécuté dans l'environnement OSS-Fuzz, ce qui suppose que le projet cible y soit déjà intégré. Quatre métriques sont alors calculées : la compilabilité, les plantages à l'exécution, la couverture à l'exécution, et un différentiel de couverture de lignes par rapport aux cibles humaines existantes. Le tableau de bugs du README associe chaque découverte à un modèle, à un prompt builder et à un target oracle, ce qui montre que ces trois éléments sont des variables d'expérience et non des détails d'implémentation. La colonne oracle mérite l'attention : elle décrit la condition qui a fait retenir la cible, par exemple une faible couverture avec un mot-clé de fuzzing et des paramètres faciles à atteindre. Autrement dit, la sélection des cibles candidates est un critère heuristique, et le jeu de résultats dépend de ce critère autant que du modèle.
Modèles pris en charge et ce que cela impose
La liste est explicite et datée. Côté Vertex AI : code-bison, code-bison-32k, Gemini Pro, Gemini Ultra, Gemini Experimental, Gemini 1.5. Côté OpenAI : GPT-3.5-turbo, GPT-4, GPT-4o, GPT-4o-mini, GPT-4-turbo, et les mêmes GPT-3.5-turbo, GPT-4 et GPT-4o via Azure. Aucun modèle local n'apparaît, aucune alternative hors de ces deux fournisseurs. La conséquence pratique est directe : faire tourner une campagne suppose un accès à Vertex AI ou une clé OpenAI, donc un coût d'inférence proportionnel au nombre de projets et au nombre de tentatives par projet. Le README ne donne aucune estimation de ce coût, et il n'y a pas de release publiée à consulter pour se faire une idée d'un changement de tarification. Le tableau des bugs est d'ailleurs dominé par Vertex AI, avec une seule ligne attribuée à un autre chemin de prompt builder. Cela ne prouve pas une supériorité de fournisseur, seulement que les expériences rapportées ont majoritairement utilisé celui-là. Le README ne publie pas les rapports complets, avec une raison assumée : ils peuvent contenir des vulnérabilités non divulguées.
Mise en route : ce que le dépôt fournit réellement
Le README ne contient pas de séquence de commandes. Il renvoie à USAGE.md pour lancer le cadre et produire des rapports, et à agent_tests/readme.md pour exécuter ou évaluer un agent isolément, sans campagne complète. Ce second point est le plus utile en pratique : la documentation décrit un cadre d'exécution d'agents qui permet de tester une séquence d'agents plutôt que l'expérience entière, ce qui réduit le périmètre et le coût d'un premier essai. Côté données, le dépôt embarque un répertoire benchmark-sets/all, décrit comme contenant plus de 1300 benchmarks issus de 297 projets open source. Les prompts se trouvent sous prompts/template_xml. Toute reproduction d'expérience suppose donc de partir de ces jeux de référence, et non d'un dépôt arbitraire. Je n'ai pas installé ni exécuté ce projet, et le matériel fourni ne permet pas de confirmer les noms exacts de variables d'environnement, de fichiers de configuration ou de points d'entrée en ligne de commande. Les chercher dans USAGE.md est la première étape, pas une formalité.
Ce que les chiffres du README disent, et ce qu'ils ne disent pas
Le README avance deux résultats : des cibles valides, c'est-à-dire générant un gain de couverture non nul, pour 160 projets C/C++, et un gain maximal de couverture de lignes de 29 % par rapport aux cibles humaines existantes. Trente bugs ou vulnérabilités sont listés comme rapportés, avec des exemples notables : CVE-2024-9143 sur openssl, une lecture hors limites sur sqlite3, une écriture hors limites sur zstd. Ces éléments proviennent d'un échantillon daté du 31 janvier 2024 pour les 1300 benchmarks, et le tableau de bugs s'étale sur plusieurs campagnes. Rien dans le matériel ne donne le taux d'échec : combien de cibles générées ne compilent pas, combien compilent sans jamais planter, combien de tentatives sont nécessaires par projet retenu. Le chiffre de 160 projets est un compteur de succès, pas un taux de réussite. La métrique de différentiel de couverture est la plus honnête du lot, parce qu'elle se compare à une base humaine, mais elle reste une mesure de couverture : une cible peut augmenter la couverture de lignes sans atteindre de chemin profond. Le README lui-même rattache certaines découvertes à des cibles à faible couverture, ce qui montre que couverture et valeur ne sont pas la même chose.
Les cas où ce n'est pas le bon outil
Trois situations disqualifient le cadre. D'abord, un projet absent d'OSS-Fuzz : la chaîne de compilation et d'exécution s'appuie sur la plateforme, et le README ne décrit aucune voie autonome pour un binaire ou un dépôt hors de ce périmètre. Ensuite, un projet dont le langage n'est pas couvert : le README mentionne C, C++, Java et Python, mais l'ensemble des résultats publiés, le tableau de bugs comme le compteur des 160 projets, concerne le C et le C++. Le support Java et Python est annoncé, sans chiffre associé dans le matériel fourni. Enfin, une équipe qui cherche un harnais utilisable immédiatement : le résultat est un artefact à évaluer, pas un livrable. Le tableau des bugs montre par ailleurs que la majorité des découvertes repose sur le prompt builder par défaut et sur un oracle permissif, ce qui suggère qu'une partie du rendement vient de la sélection des cibles plutôt que de la qualité brute de la génération. C'est une hypothèse raisonnable, pas une conclusion que le dépôt démontre.
Face à un fuzzer classique, la différence est le point de départ
Un fuzzer comme libFuzzer ou AFL++ ne produit pas de harnais : il en consomme un. Ces outils explorent un espace d'entrées à partir d'une fonction d'entrée écrite par un humain, et leur efficacité dépend entièrement de la qualité de cette fonction. oss-fuzz-gen se place en amont de cette étape et prend en charge la partie que les fuzzers laissent à l'utilisateur, avec une contrepartie : le résultat n'est pas reproductible au sens d'un algorithme déterministe, puisqu'il dépend d'un modèle, d'un prompt et d'un échantillonnage. La comparaison pertinente n'est donc pas oss-fuzz-gen contre libFuzzer, mais oss-fuzz-gen contre le temps d'ingénierie nécessaire pour écrire une cible à la main. C'est précisément ce que mesure le différentiel de couverture de lignes contre les cibles humaines d'OSS-Fuzz. Un autre point de comparaison serait un générateur d'entrées guidé par contraintes, mais le matériel fourni n'en mentionne aucun et je ne peux pas en décrire le comportement sans sortir du dépôt.
Coût de maintenance, licence et points à vérifier
Le dépôt est publié sous Apache-2.0, une licence permissive qui autorise la modification et la redistribution, avec les obligations habituelles de conservation des mentions et de l'état des modifications. Rien dans le matériel fourni ne signale de clause additionnelle ni de restriction liée aux sorties produites par les modèles, mais ce point dépasse le cadre du README et ne peut pas être tranché ici. Sur la maintenance, le dépôt n'est pas archivé et le dernier push est daté du 17 mars 2026. Aucune release n'a été récupérée : il n'existe donc pas de version étiquetée sur laquelle se fixer, et un déploiement implique de suivre la branche main. La conséquence est concrète : la liste des modèles pris en charge est un instantané, et les noms de modèles évoluent plus vite que le code qui les appelle. Un projet qui s'appuie sur ce cadre doit s'attendre à des mises à jour de la couche d'accès aux modèles, et à revérifier régulièrement que le template de prompt sous prompts/template_xml reste compatible avec les modèles disponibles. Le tableau de bugs, lui, n'est pas un journal de maintenance : il documente des découvertes passées, pas un engagement de support.
Conclusion éditoriale
À adopter si vous maintenez déjà un projet intégré à OSS-Fuzz, si vous disposez d'un accès Vertex AI ou d'une clé OpenAI, et si votre objectif est de mesurer la couverture d'une cible générée par rapport à une cible humaine existante. À éviter si vous cherchez un scanner prêt à l'emploi sur un binaire que vous ne pouvez pas compiler, ou si vous n'avez pas de budget d'inférence à consacrer à des expériences dont le résultat peut être nul. Avant tout essai, lisez USAGE.md et agent_tests/readme.md, puis vérifiez que le projet visé figure bien dans benchmark-sets/all : sans jeu de référence, la comparaison des quatre métriques perd son point d'appui.
Notes de la communauté