Pregunta

¿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 llegue a un solo lugar!

¿Fue útil?

Solución

Hay un par de cosas que debe hacer para mantener su sesión segura:

  1. Utilice SSL al autenticar usuarios o realizar operaciones confidenciales.
  2. Regenere la identificación de la sesión cada vez que cambie el nivel de seguridad (como al iniciar sesión).Incluso puede regenerar la identificación de sesión en cada solicitud si lo desea.
  3. Tener sesiones de tiempo de espera
  4. No utilice registros globales
  5. Almacene los detalles de autenticación en el servidor.Es decir, no envíe detalles como el nombre de usuario en la cookie.
  6. Comprobar el $_SERVER['HTTP_USER_AGENT'].Esto añade una pequeña barrera al secuestro de sesiones.También puede comprobar la dirección IP.Pero esto causa problemas a los usuarios que cambian de dirección IP debido al equilibrio de carga en múltiples conexiones a Internet, etc. (como es el caso en nuestro entorno aquí).
  7. Bloquee el acceso a las sesiones en el sistema de archivos o utilice un manejo de sesión personalizado
  8. Para operaciones confidenciales, considere solicitar a los usuarios registrados que proporcionen nuevamente sus detalles de autenticación.

Otros consejos

Una pauta es llamar session_regenerate_id cada vez que cambia el nivel de seguridad de una sesión.Esto ayuda a prevenir el secuestro de sesión.

Mis dos (o más) centavos:

  • No confíes en nadie
  • Filtrar entrada, escapar de salida (las cookies y los datos de la sesión también son su entrada)
  • Evite XSS (mantenga su HTML bien formado, eche un vistazo a PHPTAL o HTMLPurificador)
  • Defensa en profundidad
  • No exponer datos

Hay un libro pequeño pero bueno sobre este tema: Seguridad PHP esencial por Chris Shiflett.

Seguridad PHP esencial http://shiflett.org/images/essential-php-security-small.png

En la página de inicio del libro encontrará algunos ejemplos de código interesantes y capítulos de muestra.

Puede utilizar la técnica mencionada anteriormente (IP y UserAgent), que se describe aquí: Cómo evitar el robo de identidad

Creo que uno de los principales problemas (que se está solucionando en PHP 6) es Register_globals.Actualmente uno de los métodos estándar utilizados para evitar register_globals es utilizar el $_REQUEST, $_GET o $_POST matrices.

La forma "correcta" de hacerlo (a partir de 5.2, aunque tiene algunos errores, pero es estable a partir de 6, que llegará pronto) es mediante filtros.

Entonces en lugar de:

$username = $_POST["username"];

tu harías:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);

o incluso simplemente:

$username = filter_input(INPUT_POST, 'username');

Este documento de fijación de sesión. tiene muy buenos indicadores de dónde puede venir el ataque.Ver también página de fijación de sesiones en Wikipedia.

En mi experiencia, usar una dirección IP no es realmente la mejor idea.Por ejemplo;Mi oficina tiene dos direcciones IP que se utilizan según la carga y constantemente tenemos problemas al utilizar las 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 la información de esa sesión.Esto fue realmente útil con phpBB anterior a 3.0 (desde entonces han solucionado este problema), pero creo que sigue siendo una buena idea.

Esto es bastante trivial y obvio, pero asegúrese de sesión_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 en setTimer() y clearTimer().

El principal problema con las sesiones PHP y la seguridad (además del secuestro de sesiones) viene con el entorno en el que se encuentra.De forma 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 en todo el mundo, 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 las funciones proporcionadas para CRUD (crear, leer, actualizar, eliminar) los datos de la sesión.En ese punto, puede almacenar la información de la sesión en una base de datos o en una solución similar a Memcache para que todos los servidores de aplicaciones tengan acceso a los datos.

Almacenar sus propias sesiones también puede ser ventajoso si está en un servidor compartido porque le permitirá almacenarlas en la base de datos sobre la que muchas veces tiene más control que 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();     
}

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache agrega encabezado:

X-XSS-Protection    1

Verificaría tanto la IP como el agente de usuario 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 tu usas sesión_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 utiliza 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.Al mirar su php.ini o usar phpinfo() puede encontrar la configuración de su 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 ser accesible desde otros sitios web en su servidor compartido.

Suponiendo que aún desea usar la sesión de php, puede configurar php para que use otra carpeta cambiando _session.save_path_ o guardar los datos en la base de datos cambiando _session.save_handler_.

Es posible que puedas configurar _session.save_path_ en tu php.ini (algunos proveedores lo permiten) o para apache + mod_php, en un archivo .htaccess en la carpeta raíz de tu sitio:php_value session.save_path "/home/example.com/html/session".También puedes configurarlo en tiempo de ejecución con _session_save_path()_ .

Controlar El tutorial de Chris Shiflett o Zend_Session_SaveHandler_DbTable para configurar un controlador de sesión alternativo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top