globals off
¿ De donde vienen las variables ?
Las variables -y sus valores- pueden llegar a nuestro script PHP por distintas vias.
El autor del script puede fijar su valor dentro del propio código (variables internas); o puede permitir que sean los usuarios de la página quienes proporcionen el valor.
Las variables que pueden venir dadas desde fuera del script se llaman variables externas: pueden llegar como cadena de carácteres añadida a una url o un enlace (método get); a traves de un formulario html (método get o post), de cookies, via http (include o upload files) o a traves del servidor web que ejecuta el script (variables de entorno).
Si PHP está configurado para registrar las variables externas con alcance global (globals on en la configuracion general PHP), no tenemos forma de distinguirlas de las variables internas, y tanto unas como otras estarán automáticamente disponibles para su uso. Y esto puede ser un problema. Un visitante de la página podría crear cualquier variable, o pasar cualquier valor, y no solamente a aquellas variables pensadas para tomar su valor del usuario, sino a todas las variables. Si no filtramos cuidadosamente la entrada de datos, podemos ver comprometida la seguridad de nuestro sistema.
Considera este ejemplo, con el que php.net ilustró la necesidad de cambio de configuración por defecto de PHP:
<?php
if (authenticate_user())
{
// aqui iria la función que comprobaria si el usuario
// tiene acceso a la página, y tras las comprobaciones
// establecidas, declararía "verdadero" el valor de $user_ok
$user_ok = true;
}
// En teoria, si $user_ok = verdadero, el usuario esta validado
?>
Nada mas sencillo que llamar a la página añadiendo a la url nuestra propia variable: http://www.sitio.com/log.php?user_ok=1 y estariamos validados, aunque la función authenticate_user() devolviera un valor de usuario inválido.
La directiva register_globals
En el archivo de configuración de php (php.ini) podemos ordenar a PHP, mediante la directiva register_globals, que registre (o no) como globales las variables EGPCS, es decir, aquellas variables externas que vienen del entorno -Environment-, o via GET, POST, Cookie y Server.
Tradicionalmente PHP venia preconfigurado con este valor “on”, pero se recomienda prescindir de esta posibilidad. La configuración sugerida por defecto desde la versión 4.2.0 es la de register_globals off
Con globals en off, PHP no crea variables externas globales, lo que supone eliminar la via de ataque mas habitual, al impedir al atacante que inyecte sus propias variables con alcance global.
Por supuesto, podemos seguir introduciendo valores en el script de forma externa, pero estos valores no son ya accesibles para el script como lo son las variables internas, sino como valores de array, lo que obliga a chequear mínimamente su origen.
Configurar las globales off no supone una solución total a los problemas de seguridad. Siempre será necesario chequear y filtrar los datos enviados al script desde fuera, pero supone un gran avance ya que en primer lugar, estamos separando variables internas y externas, y de otro, tenemos clasificadas estas variables externas atendiendo a su origen (get, post, cookie etc).
Como contrapartida, encontraremos que la mayoría de los scripts de cierta complejidad que hay disponibles, han sido escritos presumiendo una configuración PHP globals on, con lo cual sencillamente, estos scripts no funcionarán con globals off. Por ello la mayoria de los grandes ISP aun tienen sus configuraciones PHP con registro global de variables.
Estamos en un periodo de transición, siendo de suponer que los programadores, tarde o temprano, iran actualizando sus scripts para dotarlos de mas seguridad, y los servidores solo ofrecerán PHP configurado de esta forma.
Como ultima nota acerca de la configuración de globals ten en cuenta que esta directiva no puede cambiarse dinámicamente con la función ini_set(), o mas exactamente si se puede, pero no sirve de nada ya que la directiva incluida en php.ini es la que se aplica al tiempo de la ejecución de tu script.
Si podriamos cambiar la configuración a traves de archivos .htaccess para servidores o carpetas concretas (php_flag register_globals off ), o si usas un servidor apache con host virtuales, y tienes acceso a los archivos de configuración del server, mediante directivas virtualhost:
<VirtualHost 127.0.0.1>
ServerName localhost
DocumentRoot /var/www/html/misitio
php_value register_globals 0
</VirtualHost>.
¿ por que globals off es mas seguro ?
PHP es un lenguaje de programación muy flexible, particularmente en el manejo de variables. En PHP no necesitas declarar o iniciar una variable antes de usarla, ni declarar el tipo de valor que puede contener (string, decimal, entero) ya que cualquier variable puede tener en principio cualquier tipo de valor.
Sin embargo, esta comodidad tambien implica un problema de seguridad, ya que cualquiera puede introducir en la ejecución de tu script nuevas variables y valores con alcance global. Por naturaleza, el código es mas seguro cuando el programador se asegura de que el valor de una variable viene de donde tiene que venir y pertenece al tipo que se le supone.
Con globals on hay que poner un cuidado especial en la validación de los datos introducidos por los usuarios y en las variables no inicializadas por el propio script antes de su uso.
Por contra, si tenemos desactivada esta opción, la variable no se crea directamente, y solo podemos acceder a su valor via superglobales, con lo que implícitamente estamos asegurandonos de que el valor de esa variable viene proporcionado por el método (get, post) previsto.
Las variables internas quedan asimismo aisladas, ya que por ejemplo, si usamos una variable $user_ok como clave para el proceso de autentificación del usuario, nadie podrá falsificarla mediante la adición de una cadena a una url (http://www.sitio.net/login.php?user_ok=1), como podría hacer por el contrario con globals on
En cuanto a las variables que deben tomar su valor de una fuente externa al script, por ejemplo, la tipica variable $mail donde se almacena el email que nos proporciona el usuario, debemos acceder a ese valor mediante el empleo de $_GET['mail'] o $_POST['mail'], segun el sistema previsto de envio. Las ventajas son en primer lugar que $mail no puede ser directamente modificada. Y con $_GET y $_POST podemos saber, al menos, si el dato nos es remitido por el método get o post seleccionado por nosotros.
Superglobales
Los valores externos están ahora a nuestra disposición a través de los arrays predefinidos $_SERVER, $_ENV, $_SESSION, $_COOKIE, $_GET y $_POST
- $_GET['variable'] – Variables proporcionadas via HTTP GET.
- $_POST['variable'] – Variables proporcionadas via HTTP POST.
- $_COOKIE['variable'] – Variables proporcionadas via HTTP cookies.
- $_REQUEST['variable'] – Variables proporcionadas via GET, POST, o COOKIE.
- $_GLOBALS['variable'] – Array con todas las variables de alcance global.
- $_SERVER['variable'] – Variables via servidor o relacionadas con el entorno de ejecución.
- $_FILES['variable'] – Variables via upload archivos
- $_ENV['variable'] – Variables del entorno
- $_SESSION['variable'] – Variables registradas en una sesión
Coexistiendo con globals on
A veces la configuración óptima de PHP no será opción para nosotros, bien porque nuestra página está en un servidor comercial, bien porque necesitamos usar un script que precisa globals on para funcionar. He aqui unas pocas pistas que ayudarán a mejorar la seguridad:
- Inicializa, al comienzo de cada script, cada una de las variables internas, especialmente aquellas que uses como control de clausulas condicionales. Asi se evita que puedan ser suplantadas por variables introducidas por el usuario, ya que el script al ejecutarse reinicializará su valor.
- Configura el nivel de mensajes de error al máximo, mientras realizas cambios en el script, ya que asi recibirás información complementaria del sistema (por ejemplo, advertencias de variables no inicializadas). Suprime los mensajes de error cuando subas el script a tu página, ya que pueden ofrecer información interna valiosa para un posible atacante.
- Filtra siempre los datos remitidos por los usuarios.
- Es efectivo chequear también la lóngitud de los datos remitidos.
- No olvides que las cookies puedes ser fácilmente manipuladas, o que cualquier persona puede crear un formulario html y apuntarlo a tu página, pasando los valores via post.
- Las funciones que permiten subir archivos a tu página son especialmente sensibles.
- Procura usar siempre una version PHP actualizada … o utilizar un ISP que sea diligente al actualizar sus servidores.
- Si usas scripts hechos por terceros, estate al tanto de las actualizaciones.
Coexistiendo con globals off
Básicamente debes recordar que las variables que pasas de una página a otra via formulario, o las que recibes via url, deben ser leidas por el script no directamente, sino de la supervariable correspondiente
<?php
// si tenemos que procesar una url con variables, similar a
// http://www.mipagina.com/index.php?op=login
print $op; // mostrara error: variable $op no definida
print $_GET["op"]; // mostrara 'login'
?>
Otras variables a las que estamos acostumbrados dejan tambien de estar disponibles de forma directa. Asi, en lugar de $PHP_SELF tendras que usar $_SERVER['PHP_SELF'];


