6 Sécurité
Manuel PHP
. Introduction . Considérations générales . Binaires CGI . Installé en tant que module Apache . Sécurité des fichiers . Sécurité des bases de données . Rapport d'erreurs ->Utilisation des variables super-globales . Données transmises par les internautes . Guillemets magiques . Masquer PHP . Etre à jour
|
6.8 Utilisation des variables super-globales
L'une des évolutions les plus controversées de PHP a été
le changement de valeur par défaut de la directive PHP
register_globals , qui est
passée de On à Off en PHP
4.2.0 .
Beaucoup d'applications dépendaient de cette directive, et de nombreux
programmeurs ne savaient même pas qu'elle existait, et supposait
que c'était le fonctionnement normal de PHP. Cette page explique
comment on peut écrire du code peu sécuritaire en utilisant
cette directive. Gardez bien en tête que cette directive,
par elle-même, n'est pas un trou de sécurité, mais qu'elle
facilite leur création.
Lorsqu'elle est activée,
register_globals
va injecter vos scripts avec toutes sortes de variables,
comme les variables issues des formulaires HTML. Ceci, couplé au fait
que PHP ne requiert pas d'initialisation de variable signifie que la
programmation de script peu sûr est possible. Ce fut une décision
difficile de la communauté PHP, mais finalement, il a été décidé
de désactiver par défaut cette variable. Lorsqu'elle est active,
le programmeur ne sait pas exactement d'où provient le contenu de la
variable, et ne peut que faire des suppositions. Les variables internes
définies dans le script sont mélangées avec les données envoyées par les
utilisateurs, et en désactivant
register_globals ,
on empêche cela. Voyons avec un exemple le fonctionnement de
register_globals :
Exemple de mésutilisation de register_globals = on |
<?php // $authorized = true uniquement si l'utilisateur est identifié if (authenticated_user()) { $authorized = true; }
// Comme nous n'avons pas initialisé $authorized avec false, cette dernière // peut être définie via register_globals, comme avec l'URL GET auth.php?authorized=1 // Tout le monde peut facilement être reconnu comme identifié! if ($authorized) { include "/donnees/critiques/data.php"; } ?>
|
Lorsque register_globals est activé, la logique ci-dessus peut être prise
en défaut. Lorsque register_globals est désactivée
$authorized
ne peut plus être assignée via la requête, et
le script est maintenant sûr, même s'il reste recommandé de toujours
initialiser ses variables. Par exemple, dans notre programme ci-dessus, nous
pourrions ajouter
$authorized = false
. En faisant cela,
le script peut fonctionner avec register_globals on ou off, car les
utilisateurs seront par défaut non-identifiés.
Un autre exemple implique les sessions .
Lorsque register_globals est activé, on peut aussi utiliser
$username
dans notre exemple, mais, encore une fois, vous
devez garder en tête que
$username
peut aussi provenir
d'autres biais, tels que GET (via l'URL).
Exemple d'abus de sessions avec register_globals on ou off |
<?php // Nous ne savons pas d'où provient $username mais nous savons que // $_SESSION contient les données de session if (isset($_SESSION['username'])) {
echo "Bonjour <strong>{$_SESSION['username']}</strong>";
} else {
echo "Bonjour <strong>visiteur</strong><br />"; echo "Voulez-vous vous identifier?";
} ?>
|
Il est même possible de prendre des mesures préventives, pour
être alerté lorsqu'une tentative d'usurpation est faite. Si vous savez
à l'avance de quelle variable le nom d'utilisateur doit provenir, vous
pouvez vérifier si les données que vous manipulez sont d'une origine
contrôlée. Même si cela ne garantit pas que les données ne puissent être
falsifiées, cela complique la tache du faussaire. Si vous ne vous
préoccupez pas de l'origine des données, vous pouvez utiliser la variable
$_REQUEST
qui contient un mélange de données GET, POST
et COOKIE. Voyez aussi la section du manuel concernant les
variables externes à
PHP .
Détection simple de fausses variables |
<?php if (isset($_COOKIE['MAGIC_COOKIE'])) {
// MAGIC_COOKIE provient d'un cookie. // Assurez-vous de valider les données du cookie!
} elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) {
mail("admin@example.com", "Tentative possible d'attaque", $_SERVER['REMOTE_ADDR']); echo "Alerte sécurité, l'admin a été prévenu."; exit;
} else {
// MAGIC_COOKIE ne provient pas de REQUEST
} ?>
|
Bien sur, désactiver l'option register_globals ne signifie pas que votre
code est sécuritaire. Pour chaque donnée reçu, vous devez appliquer un
maximum de validations. Vérifiez toujours les données de votre visiteur,
et initialisez vos variables! Pour vérifier les variables non-initialisées,
voyez la fonction
error_reporting
, qui peut afficher
les erreurs de niveau
E_NOTICE
.
Pour des informations sur l'émulation de register_globals
On ou Off, voyez la FAQ .
Note | Superglobales : disponiblité
Depuis PHP 4.1.0, les tableaux superglobaux tels que
$_GET
,
$_POST
et
$_SERVER
, etc. sont disponibles. Pour plus
d'informations, lisez la section superglobals
|
|