¿Cuáles son algunas pautas para mantener una seguridad de sesión responsable con PHP? ¡Hay información en toda la web y ya es hora de que todo aterrice en un solo lugar!
¿Cuáles son algunas pautas para mantener una seguridad de sesión responsable con PHP? ¡Hay información en toda la web y ya es hora de que todo aterrice en un solo lugar!
Respuestas:
Hay un par de cosas que hacer para mantener su sesión segura:
$_SERVER['HTTP_USER_AGENT']
. Esto agrega una pequeña barrera al secuestro de sesión. También puede verificar la dirección IP. Pero esto causa problemas a los usuarios que tienen una dirección IP cambiante debido al equilibrio de carga en múltiples conexiones a Internet, etc. (que es el caso en nuestro entorno aquí).Una pauta es llamar a session_regenerate_id cada vez que cambie el nivel de seguridad de una sesión. Esto ayuda a prevenir el secuestro de sesión.
Mis dos (o más) centavos:
Hay un libro pequeño pero bueno sobre este tema: Seguridad PHP esencial de Chris Shiflett .
Essential PHP Security http://shiflett.org/images/essential-php-security-small.png
En la página de inicio del libro encontrará algunos ejemplos de códigos interesantes y capítulos de muestra.
Puede usar la técnica mencionada anteriormente (IP y UserAgent), descrita aquí: Cómo evitar el robo de identidad
Creo que uno de los principales problemas (que se está abordando en PHP 6) es register_globals. En este momento, uno de los métodos estándar que se usan para evitar register_globals
es usar el $_REQUEST
, $_GET
o $_POST
matrices.
La forma "correcta" de hacerlo (a partir de 5.2, aunque es un poco defectuoso allí, pero estable a partir de 6, que llegará pronto) es a través de filtros .
Entonces en lugar de:
$username = $_POST["username"];
tu harías:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
o incluso solo:
$username = filter_input(INPUT_POST, 'username');
Este documento de fijación de sesión tiene muy buenos indicadores sobre dónde puede venir el ataque. Ver también la página de fijación de sesión en Wikipedia .
Usar la dirección IP no es realmente la mejor idea en mi experiencia. Por ejemplo; mi oficina tiene dos direcciones IP que se usan según la carga y constantemente nos encontramos con problemas al usar direcciones IP.
En cambio, opté por almacenar las sesiones en una base de datos separada para los dominios en mis servidores. De esta manera, nadie en el sistema de archivos tiene acceso a esa información de sesión. Esto fue realmente útil con phpBB antes de 3.0 (desde entonces lo han solucionado), pero creo que sigue siendo una buena idea.
Esto es bastante trivial y obvio, pero asegúrese de session_destroy después de cada uso. Esto puede ser difícil de implementar si el usuario no cierra sesión explícitamente, por lo que se puede configurar un temporizador para hacerlo.
Aquí hay un buen tutorial sobre setTimer () y clearTimer ().
El principal problema con las sesiones y la seguridad de PHP (además del secuestro de sesión) viene con el entorno en el que se encuentra. De manera predeterminada, PHP almacena los datos de la sesión en un archivo en el directorio temporal del sistema operativo. Sin ningún pensamiento o planificación especial, este es un directorio legible a nivel mundial, por lo que toda la información de su sesión es pública para cualquier persona con acceso al servidor.
En cuanto a mantener sesiones en múltiples servidores. En ese punto, sería mejor cambiar PHP a sesiones manejadas por el usuario donde llama a sus funciones proporcionadas a CRUD (crear, leer, actualizar, eliminar) los datos de la sesión. En ese momento, podría almacenar la información de la sesión en una base de datos o una solución similar a Memcache para que todos los servidores de aplicaciones tengan acceso a los datos.
El almacenamiento de sus propias sesiones también puede ser ventajoso si está en un servidor compartido porque le permitirá almacenarlo en la base de datos, que a menudo tiene más control sobre el sistema de archivos.
Configuré mis sesiones así:
en la página de inicio de sesión:
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);
(frase definida en una página de configuración)
luego en el encabezado que se encuentra en el resto del sitio:
session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {
session_destroy();
header('Location: http://website login page/');
exit();
}
session.cookie_httponly = 1
change session name from default PHPSESSID
X-XSS-Protection 1
X-XSS-Protection
no es realmente útil en absoluto. De hecho, el algoritmo de protección en sí podría ser explotado, lo que lo hace peor que antes.
Verificaría tanto IP como User Agent para ver si cambian
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
|| $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
//Something fishy is going on here?
}
Si usa session_set_save_handler () , puede configurar su propio controlador de sesión. Por ejemplo, podría almacenar sus sesiones en la base de datos. Consulte los comentarios de php.net para ver ejemplos de un controlador de sesión de base de datos.
Las sesiones de base de datos también son buenas si tiene varios servidores; de lo contrario, si usa sesiones basadas en archivos, deberá asegurarse de que cada servidor web tenga acceso al mismo sistema de archivos para leer / escribir las sesiones.
Debe asegurarse de que los datos de la sesión estén seguros. Mirando tu php.ini o usando phpinfo () puedes encontrar la configuración de tu sesión. _session.save_path_ te dice dónde se guardan.
Verifique el permiso de la carpeta y de sus padres. No debe ser público (/ tmp) ni accesible desde otros sitios web en su servidor compartido.
Suponiendo que aún desea usar la sesión de php, puede configurar php para usar otra carpeta cambiando _session.save_path_ o guardar los datos en la base de datos cambiando _session.save_handler_.
Usted puede ser capaz de establecer _session.save_path_ en su php.ini (algunos proveedores permiten) o para Apache + mod_php, en un archivo .htaccess en la carpeta raíz del sitio:
php_value session.save_path "/home/example.com/html/session"
. También puede configurarlo en tiempo de ejecución con _session_save_path () _.
Consulte el tutorial de Chris Shiflett o Zend_Session_SaveHandler_DbTable para establecer un controlador de sesión alternativo.