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[/b] ? Et bien les variables globales regroupent en fait toutes les variables dont la source provient de "l'extérieur", que l'on nomme [b]variables d'environnement[/b] ou [b]superglobales[/b]. C'est à dire qu'elles stockent les valeurs de [b]$_GET[/b], [b]$_POST[/b], [b]$_COOKIE[/b], [b]$_SERVER.
[alinea]Dans les anciennes versions de PHP, ces variables étaient accessibles de manière globale[/b]. Je vais vous donner un exemple ne paniquez pas, c'est en faite simple à comprendre ! Quand le [b]register_globals[/b] est activé, les variables provenant de $_GET['variable'], $_POST['variable'], $_COOKIE['variable'] ou $_SERVER['variable'] sont accessibles avec [b]$variable[/b], ce qui simplifie l'écriture. Mais, nous allons le voir, cette écriture entraine des [b]problèmes de sécurité.
[/alinea]
<?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 :
<?php
echo "Voici notre variable :".$champ;
?>
Et ceci fonctionne aussi bien par un formulaire envoyé par la méthode post[/b] que [b]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 !
<!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[/b] dans mon script. Celle ci passe à [b]TRUE si le mot de passe est correct. Un petit rappel pourra vous rafraichir l'esprit :
<?php
//Traitement du formulaire
if ($pass == "coucou"){
$session_utilisateur=true;
}
?>
La variable $session_utilisateur[/b] n'a pas été [b]initialisée et là est l'erreur. Ainsi n'importe qui peut accéder à l'espace privé sans avoir le mot de passe. Comment ? me diriez vous.
Et bien si vous avez suivi vous devriez me répondre d'une voix clair et spontannée "en rajoutant ?session_utilisateur=1 dans l'url[/i]". Je donne 1 comme valeur à [i]session_utilisateur car 1 est l'équivalent de TRUE et 0 de FALSE. Essayez donc sur le script de demonstration : ?session_utilisateur=1
Vous voyez maintenant le problème qui se pose, n'importe qui peut agir sur vos variables ! Si vous ne pouvez pas passer register_globals à Off veuillez bien à initialiser vos variables. Il suffisait de mettre :
<?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[/b] et [b]$_POST.
[ul]
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[/b] est d'afficher un [b]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.
<?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.
<?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 :
<?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[/b]. Voila le .htaccess maintient donc l'état de [b]register_globals[/b] à [b]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[/b], faites bien attention à [b]initialiser vos variables.
Tutoriaux
> Programmation > PHP / MYSQL > Sécurité > Gérer les failles de register_globals |