¿Cuál es una forma relativamente segura de usar una cookie de inicio de sesión?

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 del usuario, un atacante potencial puede robar una cookie e iniciar sesión. La gente normalmente no verifica allí “la última vez en línea”.

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

¡Creo que encontré una solución inteligente!

Ventajas de este script (¿complicado?):

  • Cuando el usuario inicia sesión con Remember Me checked, se emite una cookie de inicio de sesión además de la cookie de gestión de sesión estándar. [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 el triplete 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 al usuario una nueva cookie de inicio de sesión que contiene los tres.
  • Si el nombre de usuario y la serie están presentes pero el token no coincide, se supone un robo. El usuario recibe una advertencia muy redactada y todas las sesiones recordadas del usuario se eliminan.
  • Si el nombre de usuario y la serie no están presentes, la cookie de inicio de sesión se ignora.

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

session | token | username | expire 

La cookie “Remember me” tendrá esta configuración:

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

La secuencia de comandos:

 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.
  • La cookie y la base de datos se mantendrán limpias. Los usuarios activos renuevan su cookie cada vez que inician sesión.
  • La comprobación de la sesión al principio garantiza que la base de datos no recibirá solicitudes inútiles.
  • Si un atacante roba una cookie, recibe un nuevo token, pero no una nueva sesión. Entonces, cuando el usuario real visita el sitio web con el token antiguo (no válido) pero CON una combinación válida de sesión de usuario, el usuario recibe una advertencia del posible robo. Después de volver a validar al iniciar sesión, se crea una nueva sesión y la sesión que retiene el atacante no es válida. La revalidación asegura que la víctima realmente es la víctima, y ​​no el atacante.

Referencia: http://jaspan.com/improved_persistent_login_cookie_best_practice

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

Porque al igual que en una sesión, solo tiene un identificador que es suficiente no solo para identificar a un usuario ( ¿Quién es? ) Sino también para autenticar a ese usuario ( ¿Es realmente él / ella? ) Sin realizar una autenticación real.

Pero opuesto a una sesión que tiene (o debe tener) solo un tiempo de vida corto (generalmente menos de una hora) y el identificador es (o debe ser) cambiado periódicamente (basado en el tiempo y en la necesidad debido a cambios de estado de autoridad / autenticidad) , el identificador “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.

Entonces, antes de preguntar cómo implementar una función de “recordarme”, debería 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 el uso de HTTPS y configure el indicador HTTPOnly y el indicador de seguridad en sus cookies . Luego, podría hacer lo siguiente para crear una función de “recordarme”:

  • Solicitud de autenticación
    Si el usuario se autentica a través de HTTPS y establece la opción “recordarme”, genere un token Remember me , guárdelo en el servidor en una base de datos “Recordarme” y configure la cookie Remember Me con el indicador de seguridad con ese valor. Luego inicie una nueva sesión y configure una bandera para recordarme .

  • Cualquier otra solicitud

    1. Si no hay una sesión actual, redirija a la página recordarme a través de HTTPS que verifica si hay una cookie para recordarme . Si hay un token de recordarme y es válido, invalídelo, genere uno nuevo, almacénelo en la base de datos “Recordarme”, establezca una cookie con ese token nuevo y cree una nueva sesión con el conjunto de indicadores recordarme . De lo contrario, redirija a la página de inicio de sesión.
    2. Si la sesión actual no es válida (asegúrese de utilizar una invalidación de sesión estricta ), redirija a la página recordarme a través de HTTPS si se establece el indicador recordarme ; 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 como la autenticación “recordarme”. Y el usuario solo es auténtico durante la sesión actual; si caduca, el usuario tiene que volver a autenticarse utilizando el token Remember me o proporcionando sus credenciales de inicio de sesión. Y a medida que el recuerdo de los tokens se almacena en la base de datos, el usuario puede invalidar cualquier token Remember me existente.

Las formas más populares:

  • Muchos scripts usan algún tipo de seguimiento de sesión. Cuando el usuario visita por primera vez el sitio web, genera una ID aleatoria única para el usuario y almacena información de sesión en el servidor y la ID 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 por defecto,

  • Algunos almacenan los datos del usuario en la cookie en sí, 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 brindan cierta seguridad, que el usuario no puede alterar los datos de la sesión, pero no protege al usuario de escuchar a escondidas. 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 este artículo , especialmente la sección llamada ¿Cómo solucionan los problemas los operadores del sitio web?

    Intereting Posts