¿Es seguro mostrar a los usuarios por qué no se permite su contraseña?

33
  

///////////////////////////////// Publicación actualizada a continuación ///////////// ///////////////

Esta pregunta ha recibido muchos éxitos, más de lo que pensé que tendría en un tema tan básico. Entonces, pensé en actualizar a la gente sobre lo que estoy haciendo. También sigo leyendo en los comentarios que estoy almacenando contraseñas como texto sin formato. Solo para aclarar No lo soy.

Mi función de validación actualizada:

public function is_password($str) {
        if (strlen($str) < 10) { // Less then 10
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (strlen($str) > 100) { // Greater then 100
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#[0-9]+#", $str)) { // At least 1 number
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#[a-z]+#", $str)) { // At least 1 letter
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#[A-Z]+#", $str)) { // At least 1 capital
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } elseif (!preg_match("#\W+#", $str)) { // At least 1 symbol
            $this -> set_message('is_password', 'Password must include at least one number, one letter, one capital letter , one symbol and be between 10 and 100 characters long.');
            return FALSE;
        } else {
            return TRUE; // No errors
        }     
    }

Cada vez que devuelve FALSE , siempre les digo que se necesita la contraseña completa.

Solo para responder algunas de las preguntas sobre por qué es tan largo:

¿Por qué no tanto tiempo? Personas en mi trabajo con las que hablo usan oraciones. Muy largos en eso.

¿Cómo me hash de mis contraseñas? / ¿Por qué usar 100 caracteres? - > solo usa un mejor algoritmo de hash

Para PHP, estoy usando lo mejor que hay para este idioma. Estoy usando esta biblioteca que es la equivalencia de PHP 5.5 de nueva API de hashing de contraseña creada por Anthony Ferrara. Mi razonamiento para este hashing el uso es simple, muy alta demanda en la CPU (si alguna vez la prueba en una caja de Linux / Windows, el uso de la CPU es del 100%). Además, el algoritmo es muy escalable debido a que el factor de costo cuanto mayor es el costo, más ardua es la tarea para que la CPU inicie sesión una persona. Última I "Probado" , puse el costo a 24 Pasé una hora completa para intentar iniciar sesión y obtuve un error de tiempo de espera de PHP antes de que pasara por la pantalla de inicio de sesión (esto fue un factor de costo absurdo). Un estudio realizado por Jeremi Gosney (ESTA ES LA DESCARGA DEL INFORME EN PDF) que probó la potencia de esta función en comparación con otras más populares (sí, más popular) llegó a la conclusión de que incluso con 25 GPU, al usar bcrypt a un costo de 5 , hash de contraseña es la última de sus preocupaciones. Yo uso un costo de 17 ...

Mi función si alguien está interesado (al menos las partes que pertenecen a este tema):

public function create_user($value) {
        $this -> CI = get_instance();
        $this -> CI -> load -> library('bcrypt');

        foreach ($value as $k => $v) {// add PDO place holder to the keys
            $vals[":$k"] = $v;
        }
        $vals[":password"] = $this -> CI -> bcrypt -> password_hash($vals[":password"], PASSWORD_BCRYPT, array("cost" => 17)); // Take old $vals[":password"] and run it through bcrypt to come up with the new $vals[":password"] 

Esperemos que esta pregunta ayude a otros por ahí.

  

///////////////////////////////// Post original a continuación ///////////// ///////////////

Actualmente estoy trabajando en un nuevo proyecto y se me ocurrió un problema.

¿Es seguro revelar sus requisitos de contraseña? Si es así, ¿por qué es seguro?

Tengo una función que realiza la validación de una contraseña y cada paso muestra al usuario por qué la validación no funciona.

Aquí está mi función:

public function is_password($str) {
    if (strlen($str) < 10) {
        $this -> set_message('is_password', 'Password too short.');
        return FALSE;
    } elseif (strlen($str) > 100) {
        $this -> set_message('is_password', 'Password is too long.');
        return FALSE;
    } elseif (!preg_match("#[0-9]+#", $str)) {
        $this -> set_message('is_password', 'Password must include at least one number.');
        return FALSE;
    } elseif (!preg_match("#[a-z]+#", $str)) {
        $this -> set_message('is_password', 'Password must contain at least one letter.');
        return FALSE;
    } elseif (!preg_match("#[A-Z]+#", $str)) {
        $this -> set_message('is_password', 'Password must contain at least one capital letter.');
        return FALSE;
    } elseif (!preg_match("#\W+#", $pwd)) {
        $this -> set_message('is_password', 'Password must include at least one symbol.');
        return FALSE;
    } else {
        return TRUE;
    }
}

Mi pensamiento al respecto es si le permitimos al "usuario" / atacante saber en qué consisten mis contraseñas, ¿no sería más fácil para el atacante saberlo? Sé que la seguridad a través de la oscuridad no es una buena práctica, pero ¿podría ser un argumento sólido en esta situación?

Me gustaría saber si estoy haciendo esto de la manera correcta. Cualquier ayuda sería genial.

    
pregunta Rixhers Ajazi 13.08.2013 - 20:21
fuente

4 respuestas

100

Si no divulgas tus "requisitos de contraseña", tus usuarios te odiarán. Algunos no lograrán encontrar una "contraseña aceptable" y llamarán al servicio de asistencia. O, peor aún, si los usuarios son clientes , entonces irán a comprar a otro lugar. ¡Una excelente manera de matar tu propio negocio!

Por otra parte, si divulgar sus "requisitos de contraseña" realmente ayuda a los atacantes de manera no despreciable, entonces sus requisitos de contraseña son muy malos: no solo antagonizan a los usuarios, sino que también restringen a los usuarios a un nivel demasiado pequeño. conjunto de posibles contraseñas.

Tenga en cuenta que los atacantes generalmente pueden adivinar bastante bien cuáles son sus "requisitos de contraseña", por ejemplo. tratando de registrarse ellos mismos.

En cualquier caso, los "requisitos de contraseña" son contraproducentes y disminuyen la seguridad, excepto por una "longitud mínima" que se puede justificar racionalmente. Así que simplemente no hagas eso. La clave para la seguridad de la contraseña es educación del usuario , posiblemente con algunas herramientas (por ejemplo, un generador aleatorio para contraseñas seguras). Hacer cumplir las restricciones no ayuda; y hacer cumplir las restricciones ocultas es simplemente peor. Por ejemplo, si sus reglas requieren al menos un dígito y un símbolo, entonces una proporción sorprendentemente alta de usuarios simplemente agregará "1". al final de su contraseña; Los atacantes lo saben. El sufijo adicional no agregará mucho a la entropía de la contraseña (es decir, la cantidad de contraseñas potenciales que el atacante debe intentar para una interrupción exitosa) pero utilizará parte del recurso escaso conocido como "paciencia del usuario": los usuarios preferirán las contraseñas más cortas, Ya que tienen que agregar el "1". sufijo para apaciguar tu servidor.

    
respondido por el Tom Leek 13.08.2013 - 21:00
fuente
27

Si no le dice al usuario exactamente lo que necesita en su contraseña para realizar la validación de su función, ¿cómo sabría qué agregar o modificar para que sea válida?

Dar esa información podría hacer que un ataque de fuerza bruta sea más fácil. Sin embargo, considerando sus requisitos, no ayuda al atacante en absoluto porque hay demasiadas posibilidades de contraseña para hacer que un ataque valga la pena.

    
respondido por el Simon 13.08.2013 - 20:38
fuente
17

Los usuarios / clientes probablemente se abstendrán de usar su servicio una vez que haya fallado su tercer intento de ingresar una contraseña válida. Por el contrario, los piratas informáticos intentarán registrarse de forma arbitraria para determinar los requisitos de su contraseña con la mayor precisión posible.

Para contrarrestar esto, primero valide al usuario a través de los medios habituales (correo electrónico, captcha, etc.) y envíele un token de contraseña. Esto ya reduce la cantidad de usuarios válidos falsos, y al bloquear demasiados cambios de contraseña en un momento específico, la vida de los hackers se vuelve más difícil. Sin embargo, aún debe revelar los requisitos de contraseña de todos a más tardar después del primer intento de ingresar una no válida.

Pero mejor aún, recomiendo no obligar a los usuarios a elegir una contraseña arbitrariamente compleja que simplemente terminarán escribiendo en un post-it al lado de su monitor (o hacer que restablezcan su contraseña como "inicio de sesión" simplificado). En su lugar, hágales saber que su contraseña es débil, dígales qué es una contraseña buena pero memorable (p. Ej., Use una contraseña en su lugar) y permítales continuar de todos modos después de Al hacer clic en "Sí, entendí que mi contraseña no es muy segura, déjeme continuar de todos modos": es su culpa si la cuenta es hackeada en ese momento y no debería ser responsable después de esta advertencia explícita. Suponiendo que usted usó un hashing de contraseña correcto y establecido en lugar de homebrew-crap o, peor aún, de texto sin formato.

    
respondido por el Tobias Kienzler 14.08.2013 - 11:40
fuente
8

Piense en el escenario: ¿cómo obtiene el atacante los requisitos? Lo más probable es que puedan registrarse ellos mismos. En cuyo caso es trivial aplicar ingeniería inversa a sus requisitos, a menos que sean demasiado complejos para usarlos sin una explicación. Entonces, sí, es seguro que el usuario sepa cuáles son sus requisitos.

Pero un mejor enfoque es no requerir una contraseña, OpenID si es posible. Es casi seguro que será al menos tan seguro como lo que use para recopilar y almacenar contraseñas. Y para cualquiera con una cuenta de gmail o yahoo, definitivamente será más fácil.

    
respondido por el jmoreno 14.08.2013 - 03:45
fuente

Lea otras preguntas en las etiquetas