Voici une explication détaillée du fonctionnement algorithmique du script taint_tracker.py
, qui implémente une analyse statique par suivi de taint (taint tracking) pour
détecter les vulnérabilités dans le code PHP, telles que les injections SQL, les XSS ou les contournements d’authentification. Je vais décomposer son algorithme étape par
étape pour clarifier comment il suit les flux de données potentiellement dangereux.
Le script commence par poser les bases de son analyse :
- Chargement des Règles : Il lit un fichier DSL (par exemple,
rules.dsl
) qui définit :- Les sources : des points d’entrée de données non fiables, comme les superglobales PHP (
$_GET
,$_POST
,$_REQUEST
). - Les sinks : des fonctions ou instructions sensibles où l’utilisation de données non sécurisées peut causer des problèmes (par exemple,
mysqli_query
,echo
). - Les filtres : des fonctions de sanitization qui sécurisent les données (par exemple,
htmlspecialchars
,mysqli_real_escape_string
).
- Les sources : des points d’entrée de données non fiables, comme les superglobales PHP (
- Analyse Syntaxique : Le script utilise la bibliothèque
tree_sitter
pour parser le code PHP et construire un arbre syntaxique abstrait (AST), qui représente la structure hiérarchique du code sous forme de nœuds (variables, fonctions, assignations, etc.).
La première étape consiste à repérer les données non fiables :
- Le script parcourt l’AST pour identifier les sources définies dans les règles.
- Par exemple, une superglobale comme
$_GET['id']
est détectée via une méthode commeis_source
, qui utilise des expressions régulières pour repérer des patterns tels que$_GET[*]
. - Toute variable directement issue d’une source (par exemple,
$id = $_GET['id'];
) est immédiatement marquée comme tainted (contaminée).
Une fois une source identifiée, le script suit la propagation des données tainted à travers le code :
- Assignations : Si une variable est assignée à partir d’une source tainted (ex. :
$id = $_GET['id'];
), elle devient tainted. Cela est géré par une fonction commehandle_assignment
. - Propagation via Fonctions : Si une fonction retourne une valeur tainted (vérifié par une méthode comme
has_tainted_return
), toute variable recevant ce retour est marquée tainted. Par exemple,$result = tainted_function();
rend$result
tainted. - Expressions : Si une variable tainted est utilisée dans une expression (ex. :
$var = $id . "test";
), la nouvelle variable ($var
) hérite du statut tainted.
Le suivi est dynamique et suit les flux de données à travers les variables et les appels de fonctions.
Les sinks sont les endroits où les données tainted peuvent causer des vulnérabilités :
- Le script identifie les nœuds de l’AST correspondant aux sinks définis dans les règles (ex. :
mysqli_query
,echo
). - Pour chaque sink, il analyse les arguments :
- Si une variable tainted est utilisée dans un argument critique (par exemple, la requête SQL dans
mysqli_query($conn, $tainted_sql)
), une vulnérabilité potentielle est signalée. - Cette vérification est faite en comparant les variables utilisées dans le sink avec leur statut tainted.
- Si une variable tainted est utilisée dans un argument critique (par exemple, la requête SQL dans
La sanitization peut empêcher une vulnérabilité :
- Détection des Filtres : Les fonctions de sanitization (ex. :
htmlspecialchars
,mysqli_real_escape_string
) sont reconnues à partir des règles. Quand une variable tainted passe par un filtre (ex. :$safe = htmlspecialchars($input);
), elle est marquée comme sanitizée pour les vulnérabilités spécifiques associées (par exemple, XSS pourhtmlspecialchars
). - Vérification avant Alerte : Avant de signaler une vulnérabilité dans un sink, le script vérifie si la variable tainted a été sanitizée pour le type de vulnérabilité lié au sink. Si c’est le cas, aucune alerte n’est émise.
Le cœur de l’algorithme repose sur l’identification des problèmes :
- Sinks Dangereux : Si une variable tainted non sanitizée atteint un sink (ex. :
echo $tainted_var;
), une vulnérabilité est ajoutée à une liste (par exemple, XSS pourecho
). - Avertissements Complémentaires : Le script peut aussi signaler :
- Des variables tainted qui ne sont pas sanitizées, même si elles n’atteignent pas un sink.
- L’utilisation de filtres non optimaux (par exemple,
htmlentities
au lieu d’un filtre recommandé commesanitize_text_field
).
L’analyse repose sur une exploration systématique de l’AST :
- Handlers par Type de Nœud : Un dictionnaire (
node_handlers
) associe chaque type de nœud (assignation, appel de fonction, expression, etc.) à une fonction spécifique qui :- Propage le taint (ex. : pour une assignation).
- Détecte des vulnérabilités (ex. : pour un sink).
- Récursivité : Une méthode comme
track_taint
parcourt l’AST récursivement, appliquant les handlers à chaque nœud pour suivre les flux de données.
Le script prend en compte les fonctions personnalisées :
- Analyse des Définitions : Il recherche les définitions de fonctions dans l’AST pour déterminer si elles retournent des valeurs tainted.
- Paramètres : Si une fonction est appelée avec un argument tainted (ex. :
my_function($tainted_var)
), les paramètres correspondants dans la définition de la fonction sont marqués tainted, et leur utilisation est suivie.
Voici un exemple illustrant le processus :
- Source :
$id = $_GET['id'];
→$id
est tainted (données non fiables). - Propagation :
$var = $id;
→$var
devient tainted par assignation. - Sink :
echo $var;
→$var
est tainted et non sanitizé → une vulnérabilité XSS est signalée. - Sanitization : Si on avait
$safe = htmlspecialchars($var); echo $safe;
, aucune vulnérabilité ne serait détectée, car$safe
est sanitizé pour XSS.
Des tests unitaires sont intégrés pour vérifier :
- La détection correcte des vulnérabilités dans les cas non sanitizés.
- L’absence de faux positifs quand la sanitization est appliquée.
- La génération d’avertissements appropriés pour les cas limites.
Le script taint_tracker.py
est un outil d’analyse statique qui détecte les vulnérabilités dans le code PHP en suivant les flux de données depuis les sources non
fiables jusqu’aux sinks sensibles, tout en tenant compte des filtres de sanitization. En parcourant récursivement l’AST avec des handlers spécialisés, il
identifie les points faibles avant l’exécution du code, offrant une approche proactive pour améliorer la sécurité des applications PHP.