L’apprentissage machine
L’ajout d’apprentissage machine à l’analyse statique réalisée par Find Security Bugs est le point central, et la principale contribution apportée par ce mémoire. La section suivante définit et détaille avec précision la mise en place de ce processus.
Définition
Formellement, le terme apprentissage machine fait référence à l’apprentissage automatisé d’un modèle statistique : à partir de données, la machine tente de résoudre une tâche spécifique. Si les performances sur cette tâche s’améliorent avec les données d’entraînement, on dit que la machine apprend. L’aspect très systématique de ce processus permet de réaliser des tâches complexes ou redondantes, qu’un autre algorithme moyen ou un être humain auraient des difficultés à résoudre.
Concrètement, un problème d’apprentissage machine comporte toujours les éléments spécifiques suivant :
• des données;
• un algorithme d’apprentissage;
• une tâche à accomplir;
• une mesure des performances.
Cependant, deux types différents d’approche sont régulièrement utilisés : l’approche supervisée et l’approche non supervisée.
L’apprentissage supervisé est utilisé lorsque les classes à prédire sont connues. En d’autres termes, on sait ce que l’on cherche. Cette approche nécessite un jeu de données d’entraînement, qui ont été au préalable labélisées (par un expert par exemple). Le processus se passe en deux temps : la première phase, dite phase d’entraînement, consiste à entraîner l’algorithme d’apprentissage machine sur les données labélisées. Ainsi, celui-ci va trouver lui-même un lien entre les caractéristiques des données, et leur classe à prédire (classe qui est renseignée dans ces données d’entraînement). Les méthodes pour y parvenir sont diverses, et varient en fonction de l’algorithme utilisé. La seconde phase, dite phase de classification (ou test), consiste à donner à l’algorithme entraîné (ou modèle) une nouvelle donnée non labélisée : le but étant que celui-ci détermine automatiquement la classe à laquelle cette donnée appartient.
L’approche non supervisée, en revanche, est utilisée lorsque l’on ne sait pas réellement ce que l’on cherche : on parle de clustering. Concrètement, on dispose d’un ensemble de données, et l’algorithme va essayer par lui-même de diviser les données en groupes homogènes en fonction de leurs caractéristiques. Cela peut être très utile, car certaines ressemblances sont cachées, et l’ensemble de données peut être très grand, rendant complexe pour un humain la mise en évidence d’un regroupement efficace. Cependant, une fois les données groupées, ce sera à lui de trouver un sens à cette répartition, et éventuellement déterminer une classe pour chaque groupe.
Dans notre cas d’étude, nous utilisons une approche supervisée : le but est en effet de réaliser une classification des alertes levées par Find Security Bugs , il permet de détecter efficacement la majeure partie des vulnérabilités, même si les résultats sont parasités par des faux positifs. Le but ici n’est donc pas d’améliorer la détection (on ne fait rien contre les faux négatifs, à savoir les vulnérabilités n’ayant pas été trouvées), mais de rendre les résultats plus cohérents en mettant de côté les fausses alertes. Ainsi, pour chaque alerte, le résultat de l’algorithme est une valeur discrète, une catégorie (Vraie vulnérabilité ou Faux positif). De plus, nous entraînons l’algorithme sur un jeu de données labélisées .
Librairie Weka
Afin d’utiliser de l’apprentissage machine pour notre problème, nous avons dû trouver une implémentation accessible et utilisable de différents algorithmes adéquats. Pour cela, nous avons utilisé la librairie Weka (Weka, 1997).
Weka est un logiciel de source libre proposant une large collection d’algorithmes d’apprentissage machine, ainsi que des méthodes de visualisation. Il est entièrement implémenté en Java, ce qui est très pratique au niveau de la portabilité (il fonctionne sur tous les systèmes d’exploitation et plateformes actuels). De plus, il dispose d’une interface de programmation (API) permettant de l’utiliser directement dans du code Java, ce qui en a fait l’outil idéal pour notre problème : Find Security Bugs étant aussi codé en Java.
Il propose également de nombreuses fonctionnalités et outils d’exploration et de prétraitement des données, de classification, de régression, et de regroupement (clustering). Malgré cela, il reste très simple d’utilisation : toutes les données considérées ne proviennent que d’un fichier de type CSV (Comma-separated values), où une ligne correspond à une instance avec ses différents attributs. Ces derniers peuvent d’ailleurs être filtrés ou modifiés à la guise de l’utilisateur, avant d’appliquer les algorithmes d’apprentissage machine, ce qui permet une flexibilité des tests de performance, et notamment la mise en évidence de l’importance de chaque attribut sur la classification globale. Par ailleurs, il dispose d’une interface graphique intuitive, composée de différents onglets en fonction de l’étape à laquelle l’utilisateur se trouve dans son problème : traitement préliminaire des données, sélection d’attributs, classification, visualisation, etc. Il est important de préciser que toutes ces options sont également accessibles via l’API directement dans du code Java.
Ainsi, la librairie Weka correspondait parfaitement à notre problème, aussi bien grâce à la diversité des algorithmes, et des méthodes de visualisation qu’elle propose, que grâce à son implémentation et interface de programmation qui s’intègrent parfaitement à notre cas d’étude.
Vecteurs de caractéristiques
Explications
Le vecteur de caractéristiques est, comme annoncé auparavant, l’élément le plus important d’un problème d’apprentissage machine.
Chaque instance est représentée par un certain nombre de caractéristiques, ou attributs. Ces caractéristiques seront les mêmes pour chaque donnée passée à l’algorithme, que ce soit lors de la phase d’entraînement ou de test (classification d’une instance non labélisée). En effet, l’algorithme les utilise pour construire son modèle : si une nouvelle donnée n’ayant pas les bons attributs est envoyée vers l’algorithme entraîné, le modèle n’est plus valide et la classification ne sera pas possible. De la même façon, les caractéristiques doivent représenter précisément chaque instance : on parle de sous-apprentissage, dès lors que l’algorithme n’a pas assez d’informations pour réaliser une classification efficace.
Choix des caractéristiques
Comme dit précédemment, les caractéristiques choisies dans notre étude ont pour but de représenter au mieux des propriétés que le développeur irait récupérer (notamment grâce à son environnement de développement intégré) pour déterminer si une vulnérabilité est réelle ou non.
Ces caractéristiques sont au nombre de sept, et proviennent de trois catégories principales : la localisation de la vulnérabilité dans le code, la source ou provenance de la vulnérabilité, et les appels aux interfaces de programmation (API).
INTRODUCTION |