validar usuarios usuario usando sesiones seguro para múltiples control contraseña codigo autentificación autenticación administrador php security authentication session cookies

usuarios - Desarrollar un inicio de sesión PHP seguro y una estrategia de autenticación



login seguro php (8)

Estoy desarrollando un sistema de autenticación y acceso para un nuevo sitio PHP y he estado leyendo sobre los diversos ataques y vulnerabilidades. Sin embargo, es un poco confuso, así que quiero verificar que mi enfoque tenga sentido.

Planeo guardar los siguientes datos:

  • En la sesión: user-id, HTTP_USER_AGENT + salado HTTP_USER_AGENT

  • En la cookie y en la base de datos: identificador aleatorio, hash + identificador salado

En cada página, planeo hacer lo siguiente:

  1. Si existe una sesión, autentifíquese con eso. Verifique que HTTP_USER_AGENT coincida con el de la sesión almacenada.

  2. Si no existe sesión, use la cookie para autenticarse. Compruebe que el token y el identificador en la cookie coincidan con los de la base de datos.

  3. Si la cookie no es válida o no existe, solicite al usuario que inicie sesión.

¿Hay algún defecto obvio en esto? Mientras establezca un tiempo de espera en la cookie, debería estar bastante seguro, ¿verdad? ¿Hay algo que me estoy perdiendo?

Muchas gracias de antemano.


-use sha1 con salt -por supuesto, debes definir que cada forma no es segura, por lo que se usa token para cada forma. Que crees cada entrada de formulario y lo desinfecte usando preg_match. Un proceso llamado saneamiento.


Algunos pensamientos al azar:

  1. ¿Qué pasa si robo la cookie de uno de sus usuarios (usando un ataque XSS al inyectar un código JS en su sitio web)? Luego me caeré en el caso 2. y, por lo tanto, podré iniciar sesión. En mi humilde opinión, si desea una autenticación realmente segura, no use las cookies de tipo "Recordarme" para almacenar las credenciales de los usuarios.
  2. Si almacena las credenciales en una cookie, no almacene la contraseña en claro.
  3. La comprobación del HTTP_USER_AGENT es un buen primer paso para evitar el secuestro de la sesión, pero ¿podría combinarlo con la dirección IP? Es mucho más difícil estar en el mismo host que tu objetivo que simplemente usar el mismo navegador.

Pero en cualquier caso, gracias por tomarse el tiempo de pensar en un buen esquema de autenticación. Muchos desarrolladores de PHP no lo hacen.

EDITAR: para el registro, permítanme aclarar un punto aquí: hay dos cookies en esta discusión. Uno configurado automáticamente por PHP para propagar el ID de la sesión (a veces, vemos sitios web que lo ponen en la URL, por ejemplo, www.example.com/page.php?sessionId = [...]), y el segundo creado por usted para almacenar las credenciales del usuario y autenticarlo cuando se pierde la sesión. El ataque XSS se aplica a ambos, es decir, un atacante podría robar la cookie de sesión y secuestrar la sesión (que tiene una vida útil limitada) o robar la cookie de las credenciales y autenticarse más tarde.


Almacenar la cookie en la base de datos es una idea HORRILBE. Significa que si un atacante tiene una vulnerabilidad de inyección sql, podría obtener acceso de inmediato sin tener que descifrar una contraseña hash.

Hablando de lo cual necesitas usar sha256 para contraseñas, si usas md5 () eres técnicamente vulnerable a los ataques y podrías recibir un número CVE.

NUNCA genere sus propios id. De sesión, use session_start () y el $ _SESSION super global.

Esta es una forma segura de redirigir a las personas. Si no mueres después del encabezado (), el resto del código php se EJECUTARÁ AUN aunque no se muestre en los navegadores normales (los hackers aún lo ven :)

header("location: index.php"); die();

Para ser honesto, si la seguridad lo confunde, no escriba sistemas de seguridad. Las personas han escrito más de 1,000 sistemas de inicio de sesión solo para PHP y la mayoría son vulnerables. Este proyecto tiene un sistema de autenticación seguro: http://code.google.com/p/michael-the-messenger/downloads/list


Depende de qué tan seguro quieras estar ..

Vulnerabilidades entre sitios: digamos que otro sitio ordena al navegador que envíe un formulario a su sitio que haga algo como publicar correo no deseado (o algo peor) si ese usuario ya inició sesión, el envío del formulario funcionará. Deberá verificar el referer y un formID oculto generado para cada formulario para protegerlo completamente.

Segundo: si tiene un tráfico alto o mediano, los ID de sesión pueden repetirse o incluso adivinarse, yo compararía con una ID generada de segunda mano que está almacenada en las cookies de los usuarios.


El esquema parece innecesariamente complejo en algunos aspectos, en el sentido de que la complejidad adicional no le proporciona ningún beneficio en cuanto a funcionalidad o seguridad.

  1. Todos los datos que envía el navegador (por ejemplo, cookies, User-agent) son falsificables. La comprobación de User-agent solo ayudará cuando el atacante esté detrás de la misma NAT que el usuario falso y el atacante esté utilizando un navegador diferente, pero no piense en cambiar el User-agent.
  2. Las sesiones almacenan la identificación de la sesión desde el lado del cliente utilizando cookies o un parámetro de consulta URL. Si desea extender la duración de una sesión, use session_set_cookie_params para mantener la cookie de sesión por más tiempo.

El User-agent no es información secreta, por lo que hashing es innecesario.

Los ataques que la cookie de sesión + control de IP remota no detectará son:

  1. el atacante está detrás de la misma NAT que el usuario
  2. Inyecciones de ataques ciegos, donde el atacante suplanta la IP del usuario. A pesar de ser solo de escritura, estos aún pueden causar algún daño.
  3. ataques que utilizan el propio navegador del usuario, como la falsificación de solicitudes entre sitios (CSRF).

2) podría evitarse si puede encontrar una forma de enviar un desafío al navegador del usuario, que debe responder antes de completar la solicitud, pero esto es complicado cuando no escribió el cliente. Con AJAX se puede hacer. 3) (según lo observado por MindStalker) puede evitarse marcando el encabezado Referer, que funciona porque los ataques CSRF no tienen la capacidad de afectar encabezados arbitrarios, y XMLHttpRequest no debe permitir que se establezca el encabezado Referer (según el W3C estándar , aunque las implementaciones pueden no ser compatibles). Con los iframes, es posible sortear una verificación Referer. Además, el encabezado del Referer podría estar bloqueado en el lado del cliente.


En mi humilde opinión también es importante que la información de la sesión se modifique después de un inicio de sesión exitoso. Para guardar la información de la sesión en una base de datos no se guarda debido a las inyecciones.


La mayoría de los sitios solo usan la sesión PHP; los datos de la sesión ($ _SESSION) están en un archivo en su servidor. Todo lo que se envía al navegador es una ID de sesión. Asegúrese de regenerar la sesión de cada solicitud ( session_regenerate_id ). No necesita enviar dos cookies ni nada.

Esto es menos vulnerable al secuestro de sesión ya que cada solicitud es una nueva ID, por lo que una antigua interceptada por un atacante es inútil.

La mejor solución, obviamente, sería usar SSL durante toda la sesión.


no debería haber. la sesión php se almacena en su servidor, no en el usuario. php simplemente deja una cookie de sesión apuntando hacia ella. si no está en alojamiento compartido, la sesión ni siquiera tiene que ser hash.

joe