Guardar las contraseñas y recordar las funciones

4

(Por cierto, todo esto está codificado en PHP, estoy seguro de que lo sabrás a partir de la siguiente función)

Al guardar contraseñas, soy consciente de que tiene que cifrar sus contraseñas, de hecho, aquí está mi código (dígame si es lo suficientemente seguro):

function hash($password)
{
    return password_hash($password, PASSWORD_BCRYPT, array(
        'cost' => 12,
        'salt' => bin2hex(openssl_random_pseudo_bytes(16))
    ));
}

Sin embargo, mi pregunta real es si estoy usando un sistema de inicio de sesión adecuado o no. En el siguiente párrafo, explicaré cómo funciona mi sistema actual y si alguien puede decirme si está bien o si necesita cambiarlo. He oído que la forma correcta en que se supone que debe hacerlo es con un token que el cliente guarda en las cookies o algo así.

Cuando el usuario llega por primera vez al sitio y su cuenta está registrada, se le solicita que inicie sesión. Con la contraseña que me proporcionaron, la coloco y verifico si coincide, con password_verify (), la contraseña en la base de datos. Una vez validados, tienen la información de inicio de sesión correcta y puedo continuar y autorizarlos. Establecí en $ _SESSION el nombre de usuario y la contraseña (que entiendo que están almacenados en el lado del servidor), y si han marcado el botón Recordarme, guardo el nombre de usuario y la contraseña (sin romper) en las cookies que caducan en 1 semana.

Cada vez que intentan realizar una nueva acción, por ejemplo, cargar una página como información de cuenta, ejecuta una función en la parte superior del código que devuelve si están autenticados o no, para verificar si están autenticados o no, comprueba $ _SESSION para el nombre de usuario y la contraseña y los autentica nuevamente. Si han marcado me recuerdan y la $ _SESSION ha caducado, toma el nombre de usuario y la contraseña de allí.

Mi preocupación es que estoy seguro de que la mayoría de los sitios web utilizan un sistema de token, de modo que cuando inicia sesión guarda un token en sus cookies y luego, en lugar de iniciar sesión cada vez, usa el token. Y también en los foros, por ejemplo, puedes verificar quién está en línea mientras que con el mío, no puedes.

¿Puede alguien responder si lo que he hecho es correcto, o debe cambiarse, o no es lo mejor pero técnicamente es seguro? Estoy seguro de que la parte de la sesión es segura y aún más segura que algunos videos que he visto; algunos dicen que puedes almacenar la ID del usuario en la sesión, lo que significa que si cambian su contraseña, todavía están registrados. Pero la parte de las cookies, me está disparando con el miedo a robarlas, guardándolas en sus cookies.

    
pregunta techraf 06.08.2016 - 14:18
fuente

4 respuestas

0

He encontrado una respuesta, para esto estoy usando JWT (s). Json Web Tokens. Son dos cadenas codificadas en base64 de datos json y una firma válida al final que valida que la información no se ha cambiado. Contiene cuándo caduca la sesión de inicio de sesión y su nombre de usuario. Es especialmente bueno si desea emplear fácilmente servidores nuevos, ya que no es necesario que se sincronice con una base de datos para iniciar sesión.

Cualquiera que quiera hacer autenticación, definitivamente lo recomiendo. Tan fácil de usar, aquí hay una biblioteca también: enlace < - Es una clase copiada de una que encontré en github excepto Lo he editado para eliminar errores y hacerlo más simple.

$key="1682da5b920f4ceb74a542922f43b2a4"/* You need to keep this to decode */
$a = new JWT;

$jwt = $a->encode(json_encode(array(
            "typ" => "JWT",
            "alg" => "HS256"
        )), json_encode(array(
            "iss" => "http://yourwebsite.com/",
            "iat" => time(),
            "exp" => time() + (20 * 60),
            "username" => "authenticated Username"
        )), $key);

        setcookie('jwt_token', $jwt, 0, '/');

Recuerde, el conjunto de datos en JWT no se puede cambiar, ya que la firma que la clave proporcionará más adelante lo mantiene de esta manera.

Cuando un usuario está intentando iniciar sesión, ejecute la función $ a- > decode (), devolverá falso si los datos han sido manipulados, por ejemplo, cambiando el nombre de usuario e intentando iniciar sesión como "administrador ".

$jwt = $this->jwt->decode($_COOKIE['jwt_token'], $key);
        if($jwt == false) {
            echo 'Invalid JWT signature, tampered with!'
        } else {
            $json = json_decode($jwt, true);

            if(time() > $json['exp']) { /* expired */ }
            if(time() < $json['iat']) { /* invalid */ }

            /* 
             VALIDATED, let them through as being the user:
             $json['username']
            */
        }

si devuelve falso, como se indicó anteriormente, la firma no es válida ya que fue manipulada. Luego puede usar la matriz json_decoded para verificar información como "exp", si time () > exp entonces ha expirado. Si el tiempo () < Entonces, también lo están falsificando. Una vez que se haya validado todo, puede verificar el nombre de usuario y estar 100% seguro de que tienen permiso para estar en la cuenta de ese usuario.

    
respondido por el user120698 07.08.2016 - 16:54
fuente
1
  

Soy consciente de que tiene que cifrar sus contraseñas, de hecho aquí está mi código (dígame si es lo suficientemente seguro)

Sí, es seguro. Sin embargo, no pasaría la sal, password_hash administra las sales automáticamente.

  

Establecí en $ _SESSION el nombre de usuario y la contraseña (que entiendo que están almacenados en el lado del servidor)

Sí, está almacenado en el lado del servidor. Aún así, no debe almacenar información confidencial en la sesión si se puede evitar, lo que en este caso puede ser (no necesita la contraseña en la sesión).

Este es un problema de seguridad, ya que puede provocar la fuga de la contraseña de texto sin formato, ya que los datos de la sesión se pueden leer en hosts compartidos, a través de inclusiones de archivos, etc.

  

si han marcado el botón Recordarme, guardo el nombre de usuario y la contraseña (sin borrar) en las cookies

De nuevo, esto no es bueno. Realmente no desea almacenar la contraseña en ningún sitio, especialmente la cookie.

Cualquier persona con acceso temporal al navegador de las víctimas ahora tendrá acceso a la contraseña de texto simple, se puede acceder a ella a través de XSS (al menos si su cookie no es httpOnly, como debería ser), y así sucesivamente.

Lo que quieres usar en su lugar es un identificador aleatorio que generas y almacenas en la base de datos (idealmente hash).

  

La parte de la sesión Estoy bastante segura de que es segura, e incluso más segura que algunos videos que he visto. Algunos dicen que solo puedes almacenar la ID del usuario en la sesión, lo que significa que si cambian su contraseña, todavía están iniciado sesión. Pero la parte de las cookies, me está disparando con el miedo a robar las galletas, guardándolas en sus cookies.

Parece que sabes que no sigues las mejores prácticas. Entonces, ¿por qué construir el tuyo aquí? Su enfoque no parece ofrecer ninguna ventaja, pero tiene algunas desventajas bastante serias.

    
respondido por el tim 06.08.2016 - 15:06
fuente
1

Recordatorio rápido:

  • No defina el salt, deje que la función password_hash () administre eso para ti. Tenga en cuenta que está en desuso en PHP7 .
  • bcrypt trunca la contraseña más de 72 caracteres y en byte NUL (\ 0). Esto es por diseño, no debido a la implementación de PHP. Por estas razones, ¿es recomendado aprobar el base64_encode () resultado del hash ('SHA-384') a password_hash () en lugar de la contraseña original directamente:
function safePasswordHash($password) {
    return password_hash(
        base64_encode(
            hash('sha384', $password, false)
        ), PASSWORD_BCRYPT, array('cost' => 12)
    );
}

Inténtalo: enlace

Basado en este artículo , también puede usar un selector aleatorio y un token para asociar a cada usuario con un estado de autenticación en una tabla separada (por ejemplo, "token_auth").

Entonces, primero genere dos cadenas aleatorias de 12 caracteres:

  • Un "selector", usado como identificador;
  • Un "validador", almacenado en texto sin formato en la cookie y en valor hash en la base de datos (campo "token"). Use SHA-256 aquí.

Luego, configura la cookie como "selector: validador", por ejemplo. "FhpyQLjXYCc9: qXE6Bh417rYg".

Para asegurarse de que la cookie sea válida, primero busque el "token" que coincide con el "selector" en su base de datos y luego compárelo con el valor SHA-256 del "validador" presente en la cookie.

Utilice la función hash_equals () para evitar posibles ataques de sincronización.

    
respondido por el ATo 07.08.2016 - 09:09
fuente
0

Su intuición de almacenar las contraseñas en texto sin formato en una cookie es correcta. No es una buena idea hacerlo, y existen alternativas más seguras. Está aprovechando sus contraseñas, pero almacenándolas en texto sin formato en la variable $_SESSION contrarresta eso: significa que si un atacante obtuvo acceso a su servidor, podría obtener las contraseñas de todos los firmados actualmente. -en usuarios.

Por lo que sé, el método estándar es exactamente como lo mencionas: usar un token. Esto es mucho más seguro: nunca tendrá que almacenar las contraseñas de sus usuarios en texto sin formato en cualquier lugar. La idea general es la siguiente:

  • Cuando un usuario publica su nombre de usuario & La contraseña para usted (a través de HTTPS), la verifica con password_verify() .
  • Si la autenticación es exitosa, guarda una cookie en la computadora del usuario con lo siguiente: username=xxxx&expiry=xxxx&digest=xxxx . Cuánto tiempo debe durar el token depende de usted. También puede agregar otras variables, como admin=true y similares.
  • El resumen es un HMAC: un código de autenticación de mensaje basado en Hash. Demuestra que solo usted (el servidor) pudo haber creado la cookie y que no fue manipulada. Puede usar hash_hmac () de PHP para esto. Tenga en cuenta que deberá guardar una clave secreta en su servidor.
  • Ahora, cuando un usuario intenta acceder a otra página, simplemente verifica que tenga su cookie y (crucialmente) que el digest= coincide con el hash_hmac() de los demás datos de la cookie. Si un usuario intenta manipular su cookie, por ejemplo. Al cambiarlo a un nombre de usuario diferente, el HMAC no validará.

Hay un muy buen artículo sobre este tema que recomiendo leer: Qué hacer y qué no hacer con la autenticación de clientes en la Web (enlace PDF).

    
respondido por el tao_oat 06.08.2016 - 15:08
fuente

Lea otras preguntas en las etiquetas