| Country Rank: | 2 |
|---|---|
| World Rank: | 16 |
| Profile Viewed: | 764 |
| Points: | 11864 |
|
11 Jul
2010
|
REGEX Injection [FR]
By: Mohammed CHERIFI
|
Salut à tous!
On verra aujourd'hui la sécurité des expressions régulières, appelées aussi expressions rationnelles, ou tout simplement REGEX pour les intimes! Si vous en usé dans vos codes, ce billet est pour vous!
Les expressions rationnelles permettent de manipuler une chaine de caractère de façon très puissante, elles sont souvent utilisées pour la validation des données, le parsing du bbcode dans les forums, également dans les commandes unix comme grep et sed, mais ce n’est pas notre sujet aujourd’hui!
Où est le problème?
Dans une expression rationnelle, il est possible d’utiliser un modificateur « e » qui permet d’évaluer le code contenu dans la chaine de remplacement, donc exécuter du code php!
Dans le language Perl ainsi que dans tous les technologies qui utilisent la librairie PCRE (Perl-compatible regular expressions), y compris PHP, ces derniers supportent l’utilisation de ce modificateur, un attaquant malveillant peut injecter du code si l’entrée n’est pas correctement filtrée!
Exemple :
Voici un code qui parse une chaine de caractère et remplace tous ce qui existe entre [b] et [/b] par CHAINE, on le mettant en majuscule!
1.$nom = "toto";2.$chaine = "Hello my name is [b]".$nom."[/b]";3.$pattern = "#\[b\](.*)\[/b\]#e" ;4.$replacement = "''.strtoupper('$1').''";5.$display = preg_replace($pattern , $replacement, $chaine);6.echo $display ;Que se passera t’il si toto s’appelle ainsi :
Dans toutes les versions PHP < 5.0.5 La chaine de remplacement deviendra : ’.strtoupper(‘\\1‘.phpinfo().’‘).’ » est le code php sera exécuté ! du coup, un attaquant peut injecter un code malveillant !
Comment se protéger?
Si jamais vous êtes amenés à utiliser des expressions rationnelles avec le modificateur « e », pensez à filtrer vos variables en utilisant la fonction escapeshellcmd, d’où notre code deviendra :
1.$nom = "simo.'phpinfo().'"; // test d'injection2.$chaine = "Hello my name is [b]".$nom."[/b]";3.$pattern = "#\[b\](.*)\[/b\]#e" ;4.$replacement = "''.strtoupper(escapeshellcmd('$1')).''";5.$display = preg_replace($pattern , $replacement, $chaine);6.echo $display ;Sinon Le plus simple est d’utiliser une version récente de PHP > 5.0.5 est le tour est joué ;)