underground.org.mx
0
  • Mayo 25, 2020, 11:37:31 pm
  • Bienvenido(a), Visitante
Por favor ingresa o regístrese.

Ingresar con nombre de usuario, contraseña y duración de la sesión
Búsqueda Avanzada  

Autor Tema: No guardar el email en texto plano en la base de datos  (Leído 923 veces)

AlbertoBSD

  • Miembro
  • *
  • Karma: +3/-0
  • Mensajes: 4
    • Ver Perfil
    • Blog AlbertoBSD
No guardar el email en texto plano en la base de datos
« on: Enero 09, 2020, 05:19:54 pm »

Consideraciones sobre la forma segura de guardar el email en la base de datos.

¿Cuando y como almacenar el email en texto plano?
Cuando se necesite enviar correos continuamente ejemplo listas de distribución, newsfeed etc.

Se almacena en texto plano en alguna tabla aparte sin poder ser relacionado con ID de algún usuario y/o tabla de Login. Si el usuario se quiere desuscribir utilizar tokens para el propósito

¿Se necesita el email en el login diario?
NO, el servidor no necesita recibir el email en el login diario. Para esto en la función login el cliente debería de hashear el password de manera sencilla, eliminar algunos nibbles o bytes de los extremos del hash y enviarlo al servidor. (Nota que esto es solo un ejemplo, métodos hay muchos, el punto es No enviar el email en texto plano)

¿Cuales son las veces que es necesario conocer el email del usuario que se registra?
Cuando el usuario se registra por primera vez. Para saber que es un email válido, crear la cuenta inactiva y activarla cuando el usuario acceda mediante el token enviado a su correo.
Cuando se le olvida su password y quiere resetearlo. Se manda link de reseteo al correo y cuando cambie el password actualizar el hash del password.
Antes de guardar el email del usuario tenemos que preguntarnos

¿Realmente necesito el email en texto plano en el mismo que el password hasheado?
Antes de guardar el email del usuario tenemos que preguntarnos

En el peor de los casos cuando Dumpean la base de datos completas mediante algun SQLi o algun otro tipo de ataque, muchas veces la información es Lakeada y termina en listas como las de "Have I been pwned" entre otras

Muchas veces el hash del password no es muy fuerte y es fácilmente forcebruteable

En estos casos prueban tu email y password en otros servicios, Lo cual debería de ser una perdida de tiempo no?, por que las personas utilizan un password diferente en cada servicio.

Soluciones:

  • No utilizar un hasheo simple en el password.
  • No mostrar el email en texto plano
  • No tener SQLi en las páginas
  • No ser hackeado

Como no sabemos a priori que clase de bugs existan en el sistema operativo, servidor web, servidor SQL, Nuestro código y demás. Mas vale estar prevenido y en el peor de los casos no exponer a los usuarios

¿Que dato valido entonces?
Un hash del mismo email protegido con alguna key, Importante: Que no sea reversible es decir que teniendo el hash no exista forma de volver al email y/o password originales.

Los siguientes códigos requieren de un archivo key_db.dat el cual se puede generar con dd leyendo de /dev/random o con el método que mas les guste.

  • metodo con hash_pbkdf2

Código: [Seleccionar]
$halgo = "sha256";
$iterations = 2000000;
$email = "user@example.com";
$password = "P4ssw0rd";
$salt = hash_file($halgo,"key_db.dat",true);
$salida_email = hash_pbkdf2($halgo,$email,$salt,$iterations,0);
$salida_password = hash_pbkdf2($halgo,$password,$salt,$iterations,0);
echo "hash email: $salida_email\n";
echo "hash password: $salida_password\n";
  • metodo Iterativo con hash_hmac
Código: [Seleccionar]
$halgo = "sha256";
$iterations = 2000000;
$data_email = "user@example.com";
$data_password = "P4ssw0rd";
$i = 0;
do {
  $data_email = hash_hmac($halgo,$data_email,$salt,true);
  $data_password = hash_hmac($halgo,$data_password,$salt,true);
}while($i++ < ($iterations - 1));
$data_email = hash_hmac($halgo,$data_email,$salt,false);
$data_password = hash_hmac($halgo,$data_password,$salt,false);
echo "hash email: $data_email\n";
echo "hash password: $data_password\n";
  • metodo Iterativo solo con hash (data y key concatenadas)
Código: [Seleccionar]
$halgo = "sha256";
$iterations = 2000000;
$data_email = "user@example.com";
$data_password = "P4ssw0rd";
$i = 0;
$data_email = substr($email,0);
$data_password = substr($password,0);
do {
  $data_email = hash($halgo,$data_email.$salt,true);
  $data_password = hash($halgo,$data_password.$salt,true);
}while($i++ < ($iterations - 1));
$data_email = hash($halgo,$data_email.$salt,false);
$data_password = hash($halgo,$data_password.$salt,false);
echo "hash email: $data_email\n";
echo "hash password: $data_password\n";
¿Es excesivo 2 millones de Iteraciones?
Depende de la capacidad de tu servidor, sin embargo hay que considerar que el poder de cómputo puede variar bastante a través de los años, y los segundos que ahora tomen hacer esas iteraciones 1 o 2 segundos, en el futuro pueden ser milisegundos. Lo cual facilita un ataque por fuerza bruta a los hashes

Yo consideraría seriamente en dejarlos unos 10 millones, o más aunque nuevamente depende de la capacidad de tu servidor

Saludos

Fuente: https://albertobsd.dev/blog/es/2020/01/no-guardar-email-en-texto-plano/
En línea