Ver Mensaje Individual
  #4 (permalink)  
Antiguo 06/09/2012, 05:43
Avatar de Triby
Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 8 meses
Puntos: 2237
Respuesta: [Aporte] Seguridad básica en PHP

Octava Parte -> Sesiones

La capacidad de PHP para manejar sesiones es una de las características que le han dado mayor auge, facilitando el conservar variables entre diferentes páginas de nuestro sitio y, como casi siempre, una validación precaria o nula es la causa de riesgos de seguridad.

Primero unas observaciones y recomendaciones:

1- Siempre debes tener en cuenta que antes de session_start(); no debes haber enviado otras salidas al navegador, esto incluye enviar encabezados, crear cookies, o mostrar cualquier caracter como salto de línea, espacio en blanco, letras y, mucho menos, código HTML.

2- Si vas a usar variables de sesión en tu sitio, asegúrate de tener siempre session_start(); al principio de tus scripts, no importa en qué momento las usarás o si hay secciones de tu sitio donde no se usarán. Esto te ayudará para que en cualquier momento puedas hacer modificaciones e incluir variables de sesión sin tener que revisar si ya incluiste la línea o no, aparte de evitarte problemas de encabezados.

3- Es recomendable "agrupar" tus variables de sesión, por ejemplo:

Código PHP:
Ver original
  1.  
  2. // Sin agrupar (no recomendable):
  3. $_SESSION['nombre'] = 'Triby';
  4. $_SESSION['rol'] = 'admin';
  5. $_SESSION['email'] = '[email protected]';
  6. $_SESSION['producto1'] = 'Disco duro SATA 520GB';
  7. $_SESSION['precio1'] = 850;
  8. $_SESSION['producto2'] = 'Pantalla LCD 19"';
  9. $_SESSION['precio2'] = 990;
  10.  
  11. // Agrupado (muy recomendable)
  12. $_SESSION['usuario'] = array(
  13.     'nombre' => 'Triby',
  14.     'rol' => 'admin',
  15.     'email' => '[email protected]'
  16. );
  17. $_SESSION['carrito'] = array(
  18.     array('Disco duro SATA 520GB', 850),
  19.     array('Pantalla LCD 19"', 990)
  20. );

Si tienes tus variables de sesión agrupadas en arreglos podrás manipularlas fácilmente y tus scripts serán más legibles.

4- Para eliminar variables de sesión sólo necesitas:

Código PHP:
Ver original
  1. // Borrar todos los datos de sesión
  2. // El manual de PHP recomienda eliminar también la cookie de sesión, tú eliges si lo haces
  3. // Opción 1
  4.  
  5. // Opción 2
  6. $_SESSION = array();
  7.  
  8. // Opción 3
  9. unset($_SESSION);
  10.  
  11. // Eliminar una variable específica
  12. unset($_SESSION['usuario']);
  13.  
  14. // También puedes eliminar solo un elemento dentro de 'usuario'
  15. unset($_SESSION['usuario']['rol']);

5- No crees variables de sesión indiscriminadamente, piensa el uso que les darás y si te serán útiles en otras páginas o tienes más alternativas. Esto no es algo muy crítico, de hecho, el único problema sería que entre scripts incluidos, constantes, variables, sesiones, consultas a base de datos, etc., satures la memoria asignada a PHP y el script se detenga.

Bien, ahora veamos los problemas de seguridad que, actualmente, es muy raro que se puedan manipular las sesiones, pero depende mucho de tus hábitos de programación.

Crear ID de sesión "personalizado" (Session fixation)

Esto sólo es posible por mala validación de scripts y propagar el id de sesión por URL. Supongamos que tenemos script.php:

Código PHP:
Ver original
  1.  
  2. if (!isset($_SESSION['visits'])) {
  3.     $_SESSION['visitas'] = 1;
  4. } else {
  5.     $_SESSION['visitas']++;
  6. }
  7.  
  8. echo $_SESSION['visitas'];

La primera vez que abres la página mostrará 1 y, conforme actualices o vuelvas a entrar, ese valor se irá incrementando. Supongamos que un usuario ingresa a script.php?PHPSESSID=ABC123 se creará una sesión con la id proporcionada y, si ingresa desde otro navegador, incluso desde otro equipo usando ese mismo parámetro, no verá el 1 que se espera, sino que continuará la suma donde se quedó en el navegador que usó al crear la id.

La mejor forma de evitar este problema es configurar PHP para que guarde la ID de sesión en cookies, que también pueden ser robadas, pero orientaremos nuestros esfuerzos a defender una "fuente más confiable" y tendremos URL's "sin basura".

Robo de sesión

Generalmente, los atacantes buscarán obtener una ID de sesión de otro usuario que les permita acceso a nuestro sitio, tanto mejor si el usuario en cuestión tiene permisos administrativos.

Cuando la ID de sesión se propaga por URL es mucho más fácil "robarla" ya que está a la vista. Guardar la id de sesión en cookies limita a los atacantes, ya que deben tener acceso al equipo para obtenerla, lo que puede ocurrir si el usario trabaja en equipos públicos o los comparte con otras personas y no tiene la precaución de cerrar su sesión (logout) después de haber navegado en el sitio.

Ya sea que el atacante pueda crear una sesión o robar la de otro usuario, la seguridad de nuestro sitio se verá comprometida sólo por una mala programación y/o que la cuenta tenga permisos suficientes para tener acceso a secciones administrativas.

En www.phpsec.org (de donde tomé parte de info para el aporte) sugieren "proteger" la sesión en base a $_SERVER['HTTP_USER_AGENT'], pero la información enviada por el navegador es tan manipulable que no creo conveniente mencionarlo, en la siguiente parte veremos qué podemos hacer al respecto.

Por cierto, hasta ahora, la forma más común de robo de cuentas no es en base a sesiones, sino a robo de correos mediante páginas que simulan ser de un servicio como hotmail; quién no ha "recibido" una postal de gusanito.com donde te piden correo y contraseña de hotmail?

Agrego punto muy importante:
Cita:
Iniciado por webankenovi Ver Mensaje
Configurar correctamente las directivas de las sessiones

ini_set('session.hash_function','whirlpool'); // md5 es el algoritmo por defecto

para no propagar el id por url

ini_set('session.use_trans_sid',0);
ini_set('session.use_cookies',1);
ini_set('session.use_only_cookies',1);

solo sera accesible la cookie desde http y no sera accesible para lenguajes de script

ini_set('session.cookie_secure',0);
ini_set('session.cookie_httponly',1);

-- Continuará --
__________________
- León, Guanajuato
- GV-Foto

Última edición por Triby; 13/12/2012 a las 17:39