Tutoriaux
> Programmation > PHP / MYSQL > Sécurité > Gérer les failles de register_globals |
Vous avez codé quelques scripts, peut-être même un espace "sécurisé" pour vos membres. Vous avez peut-être entendu parlé des failles de sécurité des variables globales sans réellement comprendre pourquoi ? Nous allons voir quels problèmes causent ces variables globales en état "On" et comment mettre en place un espace membre simple sécurisé.
Nous verrons aussi comment désactiver cette fonction, soit directement dans le fichier de configuration de PHP si vous avez votre propre serveur. Si vous avez un hébergement mutualisé, comme free par exemple, et que vous n'avez pas accès au php.ini je vais vous donner des astuces pour neutraliser ces variables globales
Chapitre 1 : Les variables globales Qu'est ce qui peut bien se cacher derrière ce nom barbare de variable globale ? Et bien les variables globales regroupent en fait toutes les variables dont la source provient de "l'extérieur", que l'on nomme variables d'environnement ou superglobales. C'est à dire qu'elles stockent les valeurs de $_GET, $_POST, $_COOKIE, $_SERVER. Code :
Dans les anciennes versions de PHP, ces variables étaient accessibles de manière globale. Je vais vous donner un exemple ne paniquez pas, c'est en faite simple à comprendre ! Quand le register_globals est activé, les variables provenant de $_GET['variable'], $_POST['variable'], $_COOKIE['variable'] ou $_SERVER['variable'] sont accessibles avec $variable, ce qui simplifie l'écriture. Mais, nous allons le voir, cette écriture entraine des problèmes de sécurité.
<?php
//Ces deux écritures entrainent le même resultat lorsque register_global est à On
echo $_GET['login'];
echo $login;
?>
Chapitre 2 : Démonstration de la faille Le chapitre précédent était purement théorique et vous n'avez peut-être pas encore compris les soucis qu'entrainaient ces variables globales. Nous allons donc illustrer cela par un exemple d'exploitation de cette faille.
Nous avons donc dit dans le chapitre précédent que le nom d'un champ de formulaire devenait automatiquement une variable PHP. La valeur d'un champ de ce type :
Code :
<input type="text" name="champ" />
peut-être lu par php de cette facon :
Code :
<?php
echo "Voici notre variable :".$champ;
?>
Et ceci fonctionne aussi bien par un formulaire envoyé par la méthode post que get. De même si vous avez un cookie qui porte comme nom $_COOKIE['mon_nom'], vous pouvez y acceder grâce à la variable $mon_nom.
(je pars du principe que le registrer_globals est encore sur On). Et pourtant non, cherchez l'erreur !Code :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title>Cette page de login n'est pas sécurisée</title>
</head>
<body>
<h1>Voici ce qui peut se passer si register_globals = On</h1>
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
Entrez votre mot de passe : <input type="password" name="pass">
<input type="submit" value="Valider" />
</form>
<?php
//Traitement du formulaire
if ($pass == "coucou"){
$session_utilisateur=true;
}
//Espace privé
if ($session_utilisateur) {
//Le mot de passe est correct
//Merci à http://k4lipk4.free.fr pour la citation
echo "<br /><h4>Bienvenue dans votre espace privé</h4><p>L'enfer ne peut attaquer les paiiens (Rimbaud) </p>";
}
?>
</body>
</html>
Chapitre 3 : Explication de la faille Nous avons travaillé avec une variable qui sert de clée pour "activer" la zone privée. Cette variable je l'ai appelée $session_utilisateur dans mon script. Celle ci passe à TRUE si le mot de passe est correct. Un petit rappel pourra vous rafraichir l'esprit :
Code :
<?php
//Traitement du formulaire
if ($pass == "coucou"){
$session_utilisateur=true;
}
?>
Code :
<?php
//initialisation de la variable
//En haut de code
$session_utilisateur=false;
?>
Chapitre 4 : Les tableaux $_GET et $_POST Je vous conseille vivement de désactiver register_globals et d'utiliser plutôt les tableaux $_GET et $_POST.
Peut-être utilisiez vous déja les tableaux $_POST et $_GET et c'est trsè bien. Vous n'avez pas pour autant perdu votre temps en lisant ce tutoriel. Je pense qu'il est important de comprendre pourquoi on ne doit pas utiliser les variables globales et pourquoi, au cas ou, il vaut mieux toujours initialiser ses variables. Voyons maintenant comment désactiver le register_globals.
Chapitre 5 : Régler register_globals sur Off Je le répète encore, je vous conseille vivement de désactiver register_globals. Pour ce faire, deux cas de figure s'offre à nous : soit vous avez un serveur dédié ou encore vous travaillez en local, soit vous êtes sur un serveur mutualisé et vous ne pouvez pas modifier le php.ini.
1. Possibilité de modifier le php.ini
Le plus simple pour savoir ou se trouve le fichier php.ini est d'afficher un phpinfo() qui affiche de nombreuses informations sur la configuration de PHP. Copiez le code suivant dans un fichier php et affichez le depuis votre serveur.
Code :
<?php
phpinfo();
?>
Repérez la ligne Configuration File (php.ini) Path et vous aurez dans la colonne de droite l'adresse du fichier php.ini sur votre serveur.
Code :
<?php
//Ce code placé en haut de page cachera toutes les erreurs de votre script php
ini_set('display_errors',0);
?>
Malheureusement on ne peut pas intervenir sur register_globals à partir de cette fonction. Voici donc deux autres possibilités :
Code :
<?php
//Astuce trouvée sur un article du journal du net
//Si le register_globals est activé
if (@ini_get('register_globals')) {
//Alors on scannes toutes les variables provenant de $_POST, $_GET, $_ENV, $_COOKIE, $_SESSION
foreach ($_REQUEST as $clef => $valeur);
//Enfin unset permet de supprimer les variables globales provenant de $_POST, $_GET, $_ENV, $_COOKIE, $_SESSION
unset($GLOBALS[$clef]);
}
?>
Code :
php_value register_globals 1
Enregistrez votre fichier et déposez le à la racine de votre ftp. Enfin, renommez le en .htaccess. Voila le .htaccess maintient donc l'état de register_globals à Off.
Vous pouvez maintenant constater qu'une fois register_globals à Off, l'astuce d'accéder à la zone d'administration par une variable en GET ne fonctionne plus : ?session_utilisateur=1.
Si toutefois vous deviez laisser activé register_globals, faites bien attention à initialiser vos variables.
Tutoriaux
> Programmation > PHP / MYSQL > Sécurité > Gérer les failles de register_globals |