Uso de Register Globals

Cap铆tulo 29. Uso de Register Globals

Quiz谩s el cambio m谩s controversial en la historia de PHP se ha dado cuando la directiva register_globals pas贸 de tener como valor por defecto ON al valor OFF en PHP 4.2.0. La dependencia sobre esta directiva era bastante com煤n y muchas personas nisiquiera estaban enteradas de que exist铆a y asum铆an que ese era el modo en que PHP trabajaba. Esta p谩gina explicar谩 c贸mo puede llegar a escribirse c贸digo inseguro con esta directiva pero tenga en mente que no es la directiva misma la que es insegura sino el uso inapropiado de ella.

Cuando se encuentra activa, la directiva register_globals inyectar谩 sus scripts con todo tipo de variables, como variables de peticiones provenientes de formularios HTML. Esto junto con el hecho de que PHP no requiere la inicializaci贸n de variables significa que es muy f谩cil escribir c贸digo inseguro. Fue una decisi贸n dif铆cil, pero la comunidad de PHP decidi贸 desahibilar esta directiva por defecto. Cuando est谩 habilitada, las personas usan variables sin saber con seguridad de d贸nde provienen y solo queda asumir. Las variables internas que son definidas en el script mismo son mezcladas con los datos enviados por los usuarios y al deshabilitar register_globals se modifica este comportamiento. Demostremos este caso con un ejemplo del uso incorrecto de register_globals:

Ejemplo 29-1. Ejemplo del uso inapropiado de register_globals = on

<?php
// definir $autorizado = true solo si el usuario ha sido autenticado

if (usuario_autenticado()) {
    
$autorizado = true;
}

// Ya que no inicializamos $autorizado como false, esta podria estar
// definida a traves de register_globals, como en el caso de GET
// auth.php?autorizado=1

// De modo que cualquier persona podria verse como autenticada!

if ($autorizado) {
    include
"/datos/muy/importantes.php";
}
?>

Cuando register_globals = on, nuestra l贸gica anterior podr铆a verse comprometida. Cuando la directiva est谩 deshabilitada, $autorizado no puede definirse a trav茅s de peticiones, as铆 que no habr谩 ning煤n problema, aunque es cierto que siempre es una buena pr谩ctica de programaci贸n inicializar las variables primero. Por ejemplo, en nuestro ejemplo anterior pudimos haber realizado primero algo como $authorized = false. Hacer esto representa que el c贸digo anterior podr铆a funcionar con register_globals establecido a on u off ya que los usuarios no ser铆an autorizados por defecto.

Otro ejemplo es aquel de las sesiones. Cuando register_globals = on, podr铆amos usar tambi茅n $nombre_usuario en nuestro siguiente ejemplo, pero nuevamente usted debe notar que $nombre_usuario puede provenir de otros medios, como GET (a trav茅s de la URL).

Ejemplo 29-2. Ejemplo del uso de sesiones con register_globals on u off

<?php
// No sabriamos de donde proviene $nombre_usuario, pero sabemos que
// $_SESSION es para datos de sesion

if (isset($_SESSION['nombre_usuario'])) {

    echo
"Hola <b>{$_SESSION['nombre_usuario']}</b>";

} else {

    echo
"Hola <b>Invitado</b><br />";
    echo
"&iquest;Quisiera iniciar su sesi&oacute;n?";

}
?>

Incluso es posible tomar medidas preventivas para advertir cuando se intente falsificar la informaci贸n. Si usted sabe previamente con exactitud el lugar de donde deber铆a provenir una variable, usted puede chequear si los datos enviados provienen de una fuente inadecuada. Aunque esto no garantiza que la informaci贸n no haya sido falsificada, esto requiere que un atacante adivine el medio apropiado para falsificar la informaci贸n. Si no le importa de d贸nde proviene la informaci贸n, puede usar $_REQUEST ya que all铆 se incluye una mezcla de variables que provienen de datos GET, POST y COOKIE. Consulte tambi茅n la secci贸n del manual sobre el uso de variables desde fuera de PHP.

Ejemplo 29-3. Detecci贸n de envenenamiento simple de variables

<?php
if (isset($_COOKIE['COOKIE_MAGICA'])) {

    
// COOKIE_MAGICA proviene de una cookie.
    // Asegurese de validar los datos de la cookie!

} elseif (isset($_GET['COOKIE_MAGICA']) || isset($_POST['COOKIE_MAGICA'])) {

   
mail("admin@example.com", "Posible intento de intromision",
        
$_SERVER['REMOTE_ADDR']);
   echo
"Violaci&oacute;n de seguridad, el administrador ha sido alertado.";
   exit;

} else {

   
// COOKIE_MAGICA no fue definida en este REQUEST

}
?>

Por supuesto, deshabilitar register_globals no quiere decir que su c贸digo vaya a ser seguro. Por cada trozo de datos que sea enviado por el usuario, 茅ste debe ser chequeado en otras formas. 隆Siempre valide los datos de los usuarios e inicialice sus variables! Para chequear por variables no inicializadas, usted puede usar error_reporting() para mostrar errores del nivel E_NOTICE.

Para m谩s informaci贸n sobre la emulaci贸n del valor On u Off de register_globals, consulte este FAQ.

Superglobals: Nota de disponibilidad: Desde 4.1.0, est谩n disponibles algunas matrices superglobales tales como $_GET, $_POST, y $_SERVER, etc. Para m谩s informaci贸n puede consultar la secci贸n superglobals