FR | EN
Page générée en 0.185 sec
Imprimer

Les erreurs à ne pas commettre lors du développement du site

Un serveur Web peut être très bien sécurisé, les plus gros trous de sécurité sont souvent applicatifs. En effet un mauvais développement peut ouvrir des portes.

3.1. Bannir les variables globales

Dans les versions inférieurs à PHP4 les variables de formulaires, de cookie et session pouvaient être récupérées simplement en la définissant. Il n'y avait donc aucune distinction entre une variable passée dans l'URL et une variable de session ! On pouvait alors très bien imaginer l'exemple suivant : quand un administrateur se log sur un site, une session est lancée et une variable admin est initialisée à 1. Pour vérifier si l'administrateur est bien logué, dans chaque page un test de ce style est fait :

if ($admin == 1)
{
	// L'administrateur est logué...
}

Il est alors offert à n'importe qui de se loguer en passant en paramètre à l'URL : admin=1

Aujourd'hui, la variable register_global de PHP est par défaut à off, ce qui oblige de passer par les tableaux $_GET, $_POST, $_COOKIE et $_SESSION pour récupérer les valeurs de ces variables. Ceci a été un pas vers un code un peu plus sécurisé. Cependant de nombreux hébergeurs ont gardé cette variable active pour des raisons de compatibilité. Dans un tel cas, il est donc nécessaire de bannir le plus possible les variables globales en encapsulant le code dans des fonctions ou classes et sans oublier d'utiliser les tableaux cités précédemment.

3.2. La validation de formulaire

Lorsque l'on intègre un formulaire dans une page, une vérification de la saisie de l'utilisateur doit être effectuée. Deux types de vérification sont souvent nécessaires : coté client en javascript et coté serveur en PHP. Seulement, que vaut réellement une vérification javascript ? D'un point de vue sécuritaire, rien. En effet, le code peut être facilement contournable et le formulaire envoyé sans vérification. Dans notre cas le javascript doit être utilisé uniquement pour limiter la saisie (nombre de caractères, champs numériques, ...), préciser les erreurs instantanément lors de la saisie, mais principalement dans le but de limiter les transactions client/serveur. La vérification coté serveur n'est quand à elle pas contournable et doit être implémentée systématiquement.

Quand à la question POST ou GET, cela doit dépendre des contraintes imposées au développement. Dans les deux cas, les risques de piratage sont existants. Par conséquent, la méthode de submit de doit pas être choisie pour des raisons de sécurité.

3.3. Le passage de paramètres

3.3.1. Download de fichiers

La réalisation d'une interface d'upload / download de fichiers sur un serveur web présente de nombreux risques. Une mauvaise implémentation permettrait à n'importe qui de récupérer les sources du site et d'envoyer un fichier php contenant un code à risque. Il est surprenant de voir le nombre de sites dans ce cas.

Prenons l'exemple de ce site : http://www.esaee.com/uploads/index.php. Ce site met à disposition des fichiers divers. Pour télécharger un fichier, il suffit de passer en paramètre le nom du fichier. Ceci est une méthode simple mais de nombreux traitements et vérifications doivent en suivre, hors ici ce n'est pas le cas ! Il est alors très facile de récupérer les sources du site en passant simplement le chemin relatif (ce logiciel est utilisé par des centaines d'autres sites...).

Le premier intérêt de passer par un script pour télécharger un fichier sur un serveur est de placer ces fichiers dans des répertoires non accessibles. Ceci permet d'affecter des droit d'accès aux fichiers suivant les clients qui se connectent. Si cette notion de droit d'accès n'existe pas, le plus simple est de placer les fichiers directement dans un répertoire du site.

Pour accéder à un fichier dans un répertoire en dehors du site, le plus sécurisé est encore de passer en paramètre le md5 du fichier. La vérification coté serveur peut se limiter alors à une correspondance entre le nom du fichier et son md5 stockés en base de donnée. Une autre solution est de passer le nom du fichier. La vérification serveur doit alors passer par un traitement du paramètre au cas où celui-ci contient des caractères non autorisés : \/:*?'<>|

3.3.2. Include

La fonction include permet d'inclure des fichiers dans un script PHP. Dans la plupart des cas, cette fonction est utilisée pour créer des pages dynamiques en séparant différents éléments constituant une page :

<?php
include 'config.php';
include 'header.php';
if (file_exists($page))
	include $page;
else
	include 'default.php';
include 'footer.php';
?>

Ce code est assez simple, il inclut la configuration, l'entête, vérifie si le fichier à inclure existe et l'inclus. Enfin, il inclut le pied de page. De cette manière, il est assez simple de détourner le script en modifiant le contenu de la variable $page par un fichier sensible :

http://serveur/index.php?page=../../../../../etc/passwd

Pour sécuriser une faille de ce genre, la solution la plus simple est de passer le nom du fichier sans son extension, celle-ci serait gérée dans le script :

...
if (file_exists($page.'.php'))
	include $page.'.php';
...

La seconde solution est de supprimer les caractères \/: évitant ainsi de changer de répertoire.

Si l'on revient sur cette faille, si le fichier passwd est effectivement retourné dans notre exemple, nous nous trouvons dans un cas où le serveur web est lancé sous l'utilisateur root ! La plupart des fichiers passwd sont shadowed, ce qui rend cette méthode assez peu efficace. Cependant, une autre méthode de hacking consiste à introduire du code PHP dans les logs du serveur puis de consulter ces logs grâce à la faille, dans le but d'exécuter ce code. L'idée est donc de passer le code PHP dans l'url (encodé en urlencode), générant une erreur d'apache. Il suffit ensuite d'appeler ce fichier :

http://serveur/index.php?page=../../../../../var/log/httpd/error_log

Ceci tente à démontrer qu'il s'agit donc d'une faille très importante (surtout si le serveur Web tourne en root).

3.3.3. System

La fonction system permet d'appeler directement des commandes systèmes. Il est donc évident que cette fonction peut comporte des risques non négligeables puisque si l'attaquant réussi à détourner le script, il gagne un accès partiel au serveur (voir complet si le démon httpd est lancé en root).

Il est important de ne pas passer les commandes par l'url (ou POST) et de les exécuter directement. Si vous y êtes obligé, la méthode la plus sécurisée est encore de limiter les commandes. Pour cela il suffit d'initialisant un tableau de correspondance entre le paramètre passé et la commande autorisée :

<?php
$command_list = array('kernel_version' => 'uname -sri', 'uptime' => 'uptime');
if (in_array($cmd, $command_list);
	system($command_list[$cmd]);
?>

Par exemple, on désire afficher la version du kernel du serveur :

http://serveur/system.php?cmd=kernel_version

Tout ceci s'applique aussi aux autres commandes exécutant des applications externes comme exec et shell_exec.

3.3.4. Mail

Tout comme les autres fonctions citées précédemment, une mauvaise utilisation de la fonction mail peut s'avérer dangereux. Cette fonction ne possède pas réellement de faille mais peut être utilisée dans le but de spammer / mailbomber des adresses email.

Si l'on se place au niveau de l'hébergeur, pour éviter qu'un utilisateur n'effectue des spam, le plus efficace est de désactiver cette fonction. Cependant, il est aussi envisageable de recoder une fonction mail personnalisée (comme font certains hébergeurs) en l'appelant par exemple email.

Au niveau utilisateur, des précautions sont aussi à prendre. Dans le cas d'envoie de mail à la validation d'un formulaire, il peut être utile de limiter le client (à un seul envoie par exemple) en récupérant son IP, celle-ci stockée en base. Ceci évitera de mailbomber l'adresse de destination en appelant en boucle la page web.

W3C - XHTML 1.0 Powered By Fedora W3C - CSS