RECHERCHE

Plan du site

BOURSE

RUBRIQUES

 
 TUTORIELS 
Eviter les trous de sécurité en Perl: quelques règles simples
Il est facile à un pirate expérimenté d'exploiter la mauvaise utilisation du code Perl, notamment lors d'appels système ou d'exécution de commandes.  (14 septembre 2001)
 

Le langage Perl n'est pas en soi un langage "à risque": le problème vient de son utilisation sous forme de scripts CGI, utilisation qui impose au programmeur d'être vigilant, car des fonctionnalités du Perl mal utilisées peuvent constituer (du fait du développeur, non du langage lui-même, répétons-le) des dangers pour la sécurité des données.

Exécution de commandes système ou de programmes externes
Il convient notamment de prendre ses précautions avec certaines fonctions utilisées pour exécuter des programmes externes ou des commandes: les fonctions exec() et system(): cette dernière admet plusieurs paramètres, le premier étant interprété comme une commande à exécuter, les suivants comme des arguments. Ainsi, imaginons que nous devons développer un CGI qui demande son identifiant à un utilisateur pour lui renvoyer le contenu d'un fichier de données le concernant. On pourrait écrire:

$user = param("identifiant");
system ("cat /usr/donnes/$user");

La commande exécutée si l'utilisateur spécifie, dans le champ "identifiant", la chaîne "monnom" est alors la suivante:

cat /usr/donnees/monnom


Mais si la chaîne spécifiée est "monnom; rm -rf", la commande exécutée est alors:

cat /usr/donnees/monnom; rm -rf

Avec les conséquences qu'on imagine...

Il aurait fallu écrire:

system("cat", "/usr/donnees/$user");

ainsi la chaîne "monnom; rm -rf" sera interprétée comme un nom de fichier, et ne causera pas de catastrophe!
Malgré cela, il reste encore possible à un malveillant de transmettre la chaîne "../../etc/passwd"...
Ainsi, system() (et exec(), fonction à laquelle ce que nous venons d'écrire s'applique également), sont à manier avec la plus grande précaution.
D'une manière générale, toute instruction invoquant un shell est une instruction à risque: il est très souvent possible, plutôt que de devoir appeler un programme externe, d'utiliser une extension (module) au langage Perl.

Au lieu d'utiliser la commande Unix cat, nous allons, plus traditionnellement, ouvrir un fichier avec la fonction Perl open():

open (DONNEES, "</usr/donnees/$user);

puis lire les données au moyen d'instructions Perl.

Les autres problèmes de sécurité
Parmi eux figurent notamment (mais il y en a d'autres), la fonction rand() qui est utilisée pour engendrer des nombres aléatoires: cette fonction produit en fait une séquence de nombres pseudo-aléatoires à partir d'une certaine valeur initiale: cette valeur initiale permet de connaître la séquence de nombres qui sera produite par rand(). Si la fonction est utilisée pour de la cryptographie, ceci est assez problématique car les hackers, s'ils ont accès à des informations ponctuelles sur la séquence, pourront reconstituer celle-ci.

Enfin, un risque de sécurité est créé par des portions de code, apparemment inoffensives, comme la suivante:

unless (-e "/tmp/monfichier")
{
   open (FICHIER, ">/tmp/monfichier");
}

Ce code vient tester l'existence du fichier /tmp/monfichier, et si celui-ci n'existe pas, il le crée et le rend disponible pour l'écriture (caractère ">").
Un hacker expérimenté, qui aurait accès au code source, pourrait se lancer dans une "course de vitesse" avec le programme, qui constitue ce qu'en anglais on appelle une "race condition". En effet, si notre hacker est capable de faire exécuter sur le serveur la commande suivante, entre le moment où la vérification de l'existence de /tmp/monfichier a été effectuée sans succès (le fichier n'existant pas), et le moment où ce fichier est rendu disponible pour l'écriture:

ln -s /tmp/monfichier /etc/fichier_de_configuration_important


Toutes les modifications apportées théoriquement à /tmp/monfichier le seront désormais au fichier de configuration important. Il s'agit là d'un véritable "détournement".

On le voit, le développeur n'est jamais trop prudent, d'autant que la liste des dangers possibles ne s'arrête pas, loin de là, à ce que nous venons d'évoquer. Une programmation rigoureuse et une bonne connaissance des systèmes sont les seules solutions pour se mettre à l'abri des attaques.

 
[ Jérôme MorlonJDNet
 
Accueil | Haut de page
 
 

 

 
 
[an error occurred while processing this directive]