2011-01-23 12 views
8

Me preguntaba ¿cuál es la forma más segura de iniciar sesión en una cookie? Si solo almacena el pase (cifrado con sal) y el nombre de usuario en la cookie y lo valida en la tabla de usuarios, un posible atacante puede robar una cookie e iniciar sesión. Normalmente, las personas no verifican que haya "última vez en línea".¿Cuál es una forma relativamente segura de utilizar una cookie de inicio de sesión?

Entonces, ¿hay una mejor manera de "recordarme la cookie"? IP no es una buena opción, ¿verdad? (Algunas máquinas cambian de IP todo el tiempo).

maneras
+1

Cuéntanos algo sobre tu aplicación que usaría esta característica. ¿Cuál sería el impacto potencial de una suplantación/robo de identidad? – Gumbo

+0

la mayoría de las máquinas cambian la IP todo el tiempo ... – Shoe

+2

la función "recordarme" es insegura por definición. Por lo tanto, depende de usted elegir entre usabilidad y paranoia. –

Respuesta

19

¡Creo que he encontrado una solución inteligente!

Las ventajas de este (complicado?) Guión:.

  • Cuando el usuario inicia sesión con éxito en con Recordarme comprobado, una cookie de inicio de sesión se emite, además de la gestión de sesiones estándar galletas [2 ]
  • La cookie de inicio de sesión contiene el nombre de usuario del usuario, un identificador de serie y un token. La serie y el token son números aleatorios inimaginables de un espacio adecuadamente grande. Los tres se almacenan juntos en una tabla de base de datos.
  • Cuando un usuario que no ha iniciado sesión visita el sitio y presenta una cookie de inicio de sesión, el nombre de usuario, la serie y el token se buscan en la base de datos.
  • Si la tripleta está presente, el usuario se considera autenticado. El token usado se elimina de la base de datos. Se genera un nuevo token , se almacena en la base de datos con el nombre de usuario y el mismo identificador de serie , y se emite una nueva cookie de inicio de sesión que contiene los tres .
  • Si el nombre de usuario y la serie son presentes pero el token no coincide, se supone un robo. El usuario recibe una advertencia muy redactada y todas las sesiones recordadas del usuario son borradas.
  • Si el nombre de usuario y la serie no son presentes, se ignora la cookie de inicio de sesión.

He hecho una tabla en la base de datos con la siguiente información:

session | token | username | expire 

El me recuerda galletas tendrá esta configuración:

$value = "$session|$token|$userhash"; //Total length = 106 
  • Session habrá una cadena de 40 (sha1) caracteres.
  • Token será una cadena de 32 (md5) caracteres.
  • Userhash en la cookie será un cadena de 32 (md5 de nombre de usuario) caracteres.
  • Username en la base de datos será el nombre de usuario normal.
  • Expire ahora serán + 60 días.

El guión:

if(isset($_SESSION['check']) || $_SESSION['check']){ 
    //User is logged in 
}else if(isset($_COOKIE['remember']) && strlen($_COOKIE['remember'])==106){ 
    //THERE is a cookie, which is the right length 40session+32token+32user+2'|' 
    //Now lets go check it... 
    conncectdb(); //Sets connection 
    //How do I protect this script form harmful user input? 
    $plode = explode('|',$_COOKIE['remember']); 
    $session = mysql_real_escape_string($plode[0]); 
    $token = mysql_real_escape_string($plode[1]); 
    $userhash = mysql_real_escape_string($plode[2]); 
    $result = mysql_query(" SELECT user 
       FROM tokens 
       WHERE session = '$session' 
       AND token = '$token' 
       AND md5(user) = '$userhash';") 
    if(mysql_num_rows($result)==1){ 
     //COOKIE is completely valid! 
     //Make a new cookie with the same session and another token. 
     $newusername = mysql_result($result,0,0); 
     $newsession = $session; 
     $newtoken = md5(uniqid(rand(), true)); 
     $newuserhash = md5($username); 
     $value = "$newsession|$newtoken|$newuserhash"; 
     $expire = time()+4184000; 
     setcookie('remember', $value, $expire, '/', 'www.example.com', isset($_SERVER["HTTPS"]), true); 
     mysql_query(" UPDATE tokens 
       SET token='$newtoken', expire='$expire' 
       WHERE session = '$session' 
       AND token = '$token' 
       AND md5(user)='$userhash';"); 
     //Set-up the whole session (with user details from database) etc... 
    } else if(mysql_num_rows(mysql_query("SELECT user FROM tokens WHERE session = '$session' AND md5(user) = '$userhash';"))==1)){ 
     //TOKEN is different, session is valid 
     //This user is probably under attack 
     //Put up a warning, and let the user re-validate (login) 
     //Remove the whole session (also the other sessions from this user?) 
    } else { 
     //Cookie expired in database? Unlikely... 
     //Invalid in what way? 
    } 
} else { 
    //No cookie, rest of the script 
} 

Ventajas de la secuencia de comandos:

  • inicio de sesión múltiple. Puede crear nuevas sesiones para cada computadora en la que se encuentre.
  • Las cookies y la base de datos se mantendrán limpias. Usuarios activos renuevan su cookie cada inicio de sesión.
  • La comprobación de la sesión al principio asegura que la base de datos no recibirá peticiones inútiles.
  • Si un atacante roba una cookie, recibe un nuevo token, pero no una nueva sesión . Por lo tanto, cuando el usuario real visita el sitio web con el token viejo (no válido) pero CON una combinación de usuario válida sesión , el usuario recibe una advertencia del posible robo. Después de volver a validar iniciando sesión se crea una nueva sesión y la sesión que tiene el atacante no es válida. La validación de garantiza que la víctima sea realmente la víctima, y ​​no el atacante .

Referencia: http://jaspan.com/improved_persistent_login_cookie_best_practice

+0

No veo nada importante en esta solución. ¿Cuál es el propósito del campo de sesión en esta tabla? ¿por qué mesa dedicada en absoluto? ¿Por qué no almacenar solo un hash hecho con los datos de algunos usuarios? –

+0

Cualquier otra solución le permitirá tener varias sesiones también, sin tabla adicional, sin complicar demasiado su secuencia de comandos –

+0

Esto limita el tiempo de que el atacante pueda usar su cuenta. – SuperSpy

3

más populares:

  • Muchos scripts utiliza algún tipo de seguimiento de sesión. Cuando el usuario visita por primera vez el sitio web, genera una identificación aleatoria única para el usuario y información de la sesión de la tienda en el servidor y la identificación en la cookie. El servidor luego identifica al usuario que usa la ID única (llamada ID de sesión). La información asociada con la ID de la sesión solo puede ser vista por el servidor. PHP usa esto de forma predeterminada,

  • Algunos almacenan los datos del usuario en la cookie, pero con una firma HMAC usando una cadena secreta como clave. El script descarta la cookie si la firma no coincide. De esta forma, el servidor no tiene que mantener los datos de la sesión en el servidor. El usuario ve lo que hay en la sesión mirando la cookie, por lo que no debe almacenar datos confidenciales en ella. Solo el ID de usuario (y posiblemente el tiempo de inicio de sesión y el tiempo de caducidad de la cookie) deberían ser suficientes. Aunque el usuario puede ver lo que está en la información de la sesión, la firma en la cookie asegura que el usuario no puede modificar los datos de la sesión él mismo.

Estas formas proporcionan cierta seguridad, que el usuario no puede manipular los datos de la sesión, pero no protege al usuario de espía. Siempre pueden usar un rastreador de paquetes y robar una sesión desde cualquier red WiFi abierta. Algunas aplicaciones dependen de la IP del usuario, pero no importa si el atacante está en la misma red. Algunas aplicaciones dependen de User-Agent, pero habrá problemas cuando el usuario actualice su navegador o importe datos desde otro navegador.

Si realmente está preocupado por la seguridad, entonces use HTTPS.

Lea también this article, especialmente la sección llamada ¿Cómo solucionan el problema los operadores del sitio web?

+0

Texto largo y no una sola palabra sobre el tema. Y un voto positivo de alguien que no lee, pero que simplemente está impresionado por el tamaño del texto. –

+0

¿No es el tema sobre las cookies de inicio de sesión y su seguridad? De eso es de lo que estoy hablando en la respuesta. – Thai

+0

Está totalmente en el tema y me dio más ideas sobre las ID de sesión y las cosas HTTPS. Lo hice upvoted. – Shoe

6

Tal “me recuerda” característica es siempre un riesgo de seguridad adicional.

Porque al igual que en una sesión sólo tiene un identificador que es suficiente no sólo para identificar a un usuario (¿Quién es?), sino también para autenticar que el usuario (¿Es realmente él/ella?) sin hacer una autenticacion real

Pero opuesto a una sesión que tiene (o debería tener) solo un tiempo de vida corto (generalmente menos de una hora) y el identificador es (o debe ser) cambiado periódicamente (basado en tiempo y en necesidad debido a autenticidad/cambios de estado de autoridad), un identificador de "recordarme" es válido por días si no es por meses o años. Y este largo período de validez plantea un riesgo de seguridad adicional.

Así que antes de preguntar cómo implementar una función de "recordarme", debe preguntarse si realmente desea ese riesgo de seguridad adicional. Eso depende principalmente de los activos que tiene su aplicación y el propósito de la autenticación, y si desea tomar el riesgo de suplantaciones/robos de identidad que la característica "recordarme" plantea.

Si es así, asegúrese de proporcionar seguridad básica mediante HTTPS y configure HTTPOnly y secure flag in your cookies. Posteriormente, se podría hacer lo siguiente para construir un “Remember Me” de estas características:

  • solicitud de autenticación
    Si el usuario autenticado a través de HTTPS y establecer la opción “me recuerda”, genera de forma aleatoria me recuerdan token, guárdelo en el servidor en una base de datos "Recordarme" y configure recuérdeme la cookie con la marca segura con ese valor. A continuación, inicie una nueva sesión y configure un recuérdeme marca.

  • Cualquier otra petición

    1. Si no hay ninguna sesión actual, redirigir a la me recuerda página a través de HTTPS que comprueba si hay un remember me galleta. Si hay un token me recuerda y es válido, invalidarlo, generar uno nuevo, almacenarlo en la base de datos "recordarme", establecer una cookie con ese token nuevo y crear una nueva sesión con el recordarme conjunto de banderas. De lo contrario, redirija a la página de inicio de sesión.
    2. Si la sesión actual no es válido (asegúrese de usar un strict session invalidation), redirigir a la me recuerda página a través de HTTPS si el remember me El indicador se establece; de lo contrario, redirija a la página de inicio de sesión.

Con esto, la autenticación se asegura a través de HTTPS, tanto la autenticación inicial y la autenticación “recuérdame”.Y el usuario solo es auténtico durante la sesión actual; si caduca, el usuario tiene que volver a autenticarse utilizando el token recordarme o proporcionar sus credenciales de inicio de sesión. Y como el me recuerda tokens se almacenan en la base de datos, el usuario puede invalidar cualquier recuerdo recuerdo token.

+0

'si realmente desea ese riesgo de seguridad adicional', puedo limitar el usuario autenticado por cookies para evitar daños. Revisa mi script a continuación, nunca recibirás un token aleatorio afortunado porque si los tokens son idénticos, el usuario debe ser dos idénticos. Quiero hacer que recordarme sea más permanente, en lugar de fijar la sesión expire a un valor más alto. – SuperSpy

+0

Esta es una respuesta, pero (para mí) no es la respuesta. – SuperSpy

Cuestiones relacionadas