2008-08-21 6 views
1

Pour ma thèse principale, j'ai développé un programme qui détecterait automatiquement et proposerait des correctifs aux vulnérabilités d'injection SQL en utilisant des instructions préparées. Plus précisément l'extension mysqli pour PHP. Ma question pour la communauté SO est la suivante: Quelle serait votre approche préférée pour détecter le code source SQL dans PHP?Meilleure approche pour analyser SQL dans des fichiers PHP?

J'ai utilisé une énumération contenant SQL keywords (SELECT, INSERT, ...) et fondamentalement analysé chaque ligne, en répétant l'énumération pour déterminer si un SQL était présent. De plus, je devais m'assurer que l'analyseur ne détecte pas html de façon erronée (par exemple < \ select>).

Pour moi cette solution a bien fonctionné, mais maintenant j'ai un peu plus de temps maintenant et j'ai pensé à refactoriser le code pour utiliser une solution plus élégante (et plus efficace). Veuillez limiter vos solutions à l'utilisation de C# car c'est ce à quoi j'ai écrit mon programme.

Répondre

1

Votre solution me semble bien. L'autre façon serait d'analyser le fichier PHP avec un analyseur Lex/Yacc en utilisant la grammaire pour PHP, il y a un bon outil d'analyse syntaxique C# appelé Coco/R http://www.ssw.uni-linz.ac.at/coco/.

Cependant, je crois que si vous analysez la langue, vous finirez par consommer trop de temps (en développement et en informatique) sans résultats supplémentaires. Je maintiendrais votre approche opportuniste, mais je la testerais par rapport à divers codes PHP et la peaufinerais pour couvrir tous les cas possibles.

1

Peut-être y a-t-il un peu de différence dans l'analyse des lignes de texte par rapport au BNF, par exemple, SQL92, et en marquant chaque ligne sur la façon dont les fragments correspondent à la grammaire.

Cela ressemble cependant à un gros travail de levage. Votre approche simple attirera déjà un si grand pourcentage de cas réels.

1

Je ne connais pas les détails des variables en C# et vous devrez pardonner ou me down-voter pour l'utilisation de PHP, mais 70% du temps ma requête SQL va dans une variable comme si

$sql = "SELECT * FROM table;"; 

Au-delà de cela, je suis incapable de penser à tout ce que vous pouvez faire pour améliorer ce que vous avez déjà.

Prenez-vous en compte les instructions créées sur plusieurs lignes et utilisez-vous des variables dans la chaîne? (Exemple ci-dessous)

$sql = "SELECT * FROM table WHERE fname = $fname OR snmae = $sname"; 
0

Je ne connais pas les détails des variables en C# et vous devrez pardonner ou me down-voter pour l'utilisation de PHP, mais 70% du temps ma requête SQL va dans une variable comme si ..

Ouais, mon approche originale était juste chercher le $ sql vars puisque c'est ce plus gens utilisent, mais après avoir testé contre quelques applications PHP je me suis vite jeté cette solution parce que certains les développeurs utilisent des noms de variables funky ...

Prenez-vous en compte les instructions créées sur plusieurs lignes et utilisez-vous des variables dans la chaîne? (Exemple ci-dessous)

Yep.J'ai également tenté de gérer des instructions générées conditionnellement, mais cela ne fonctionnait pas toujours aussi bien. ;)

0

Un regex simple de détecter toutes les instructions SQL CRUD utilisées avec des fonctions (en supposant $ script contient tout le script php)

preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?\)\s*?;/is', 
       $script, $matches); 

Il doit correspondre possible SELECT, INSERT, UPDATE, DELETE, si ils sont placés entre parenthèses et guillemets. Il est insensible à la casse et devrait également correspondre à des instructions couvrant plusieurs lignes.

éditer # 1: Regex pour l'instruction CRUD correspondante comme les affectations de chaînes;

preg_match_all('/\$\w+\s*?=\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?;/is', 
       $script, $matches); 

modifier # 2:

// $variable detecting version of #1 regex 
preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?(?:\$\w+){1}.*?"\s*?\)\s*?;/is', 
        $script, $matches); 
1

Je dirais qu'il serait préférable de rechercher des appels de fonction au lieu de chercher SQL lui-même. Modifier éventuellement l'analyseur PHP pour rechercher les appels de fonction qui aboutissent à l'exécution d'une requête SQL qui n'est pas une requête préparée.

Questions connexes