Injection de code dans une expressions rationnelle (REGEX Injection)

Regular expression injectionSalut à tous!

Aujourd’hui je vous parlerai de 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 <strong>CHAINE</strong>, on le mettant en majuscule!

[code lang=’php’]
$nom = “toto”;
$chaine = “Hello my name is [b]”.$nom.”[/b]”;
$pattern = “#\[b\](.*)\[/b\]#e” ;
$replacement = “‘‘.strtoupper(‘$1′).’‘”;
$display = preg_replace($pattern , $replacement, $chaine);
echo $display ;
[/code]

Que se passera t’il si toto s’appelle ainsi :

  • ‘.phpinfo().’
  • ‘.exec(\$_GET[cmd]).’
  • ‘.include($_GET[backdoor]).’

Dans toutes les versions PHP < 5.0.5 La chaine de remplacement deviendra : <strong>’.strtoupper(‘\\1‘.phpinfo().’‘).'”</strong> 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 :

[code lang=’php’]
$nom = “simo.’phpinfo().'”; // test d’injection
$chaine = “Hello my name is [b]”.$nom.”[/b]”;
$pattern = “#\[b\](.*)\[/b\]#e” ;
$replacement = “‘‘.strtoupper(escapeshellcmd(‘$1′)).’‘”;
$display = preg_replace($pattern , $replacement, $chaine);
echo $display ;
[/code]

Sinon Le plus simple est d’utiliser une version récente de PHP > 5.0.5 est le tour est joué ;)

2 thoughts on “Injection de code dans une expressions rationnelle (REGEX Injection)

  1. Merci pour tes articles j’adore, j’ai dévoré tes articles, en plus ils sont bien expliqué avec de vrai exemple !

    Gros bravo

Leave a Reply

Your email address will not be published. Required fields are marked *