¿Es suficiente una 'if contraseña == XXXXXXX' para una seguridad mínima?

20

Si creo un inicio de sesión para una aplicación que tiene un riesgo de seguridad medio a bajo (en otras palabras, no es una aplicación bancaria ni nada), ¿es aceptable para mí verificar una contraseña ingresada por el usuario simplemente diciendo algo como:

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

Parece fácil ser efectivo, pero ciertamente no me importaría si eso fuera todo lo que se requería. ¿Es suficiente una simple verificación del combo de nombre de usuario / contraseña?

Actualización: el proyecto en particular es un servicio web, la verificación es completamente del lado del servidor y no es de código abierto. ¿El dominio cambia cómo tratarías esto?

Morgan Herlocker
fuente
3
Depende de dónde viene la contraseña válida? Si está codificado, no podrá configurar / cambiar la contraseña sin cambiar el código. Si proviene de un archivo de configuración, será visible para cualquiera que acceda a él.
Alb
1
"¿es suficiente una verificación del combo de nombre de usuario / contraseña" para hacer qué?
Chris
3
@opinion: parece poco probable que esto sea PEOR que no tener un inicio de sesión. Proporcione algún razonamiento para un reclamo tan fuerte.
Morgan Herlocker
1
Su terminología es incorrecta, cuando compara una contraseña, la verifica, sin asegurarse de que sea válida. Tómese el tiempo para comprender la diferencia.
billy.bob
1
Esto implica el almacenamiento de contraseña de texto sin formato, que es irresponsable. También implica alertar a un usuario de que la contraseña era incorrecta, lo que proporciona al atacante potencial demasiada información. Siempre debe ser ambiguo, es decir, "Nombre de usuario o contraseña incorrectos".
Rein Henrichs

Respuestas:

26

No sin SSL

Esto no es seguro si la contraseña se envía a través de la red en texto sin formato. Hashing la contraseña en el lado del servidor tampoco es seguro si la contraseña se envía a través de la red en texto sin formato.

Dado que la <input type="password"/>etiqueta HTML envía su contenido en texto plano, esto será un problema sin importar cómo almacene la contraseña en el servidor, a menos que su sitio web use SSL para transmitir la contraseña.

(La autenticación HTTP, que aparece un cuadro de diálogo en el navegador que solicita una contraseña, puede o no ser texto claro, dependiendo de los mecanismos de autenticación que el servidor y el navegador tengan en común. De modo que podría ser una forma de evitar esto sin usar SSL.)

No si los administradores del sitio son sospechosos

Ahora, suponiendo que esté utilizando HTTPS para hacer el sitio web, esto podría ser seguro si confía en los administradores de su sitio (que pueden leer contraseñas de texto sin formato) y otras personas que tienen acceso a la máquina para comportarse correctamente. Ahora, puede ser obvio que pueden hacer lo que quieran con su sitio web (ya que lo administran), pero si pueden leer la contraseña, también pueden usar los pares de inicio de sesión / contraseña robados en los sitios de otras personas.

Una forma que mantiene las contraseñas seguras del administrador

Una forma segura de almacenar y verificar contraseñas es la siguiente:

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

Para la función hash, intente usar algo fuerte y algo que todavía no tenga buenas tablas de arco iris en la naturaleza. Puede cambiar la longitud de la sal si es necesario trabajar alrededor de las mesas de arcoiris.

Dependiendo del entorno en el que se encuentre, la variabilidad en la latencia de su red y si los nombres de usuario deben ser conocidos públicamente, es posible que desee tener otro cálculo de ruta de código hash('0000'+entered_password)si el usuario no existe, para evitar que los atacantes determinar qué nombres de usuario son válidos en función del tiempo que lleva determinar que la contraseña es incorrecta.

Ken Bloom
fuente
1
Buenos consejos :) Con respecto a SSL, se nos pidió que diseñáramos algo que funcionara en la naturaleza , y simplemente usamos criptografía asimétrica para codificar la contraseña (requiere Javascript) y luego decodificarla en el servidor. La sal + hash entonces ocurre normalmente. Además, dado que la clave pública se envía con la página web, puede cambiar arbitrariamente a menudo.
Matthieu M.
1
@Matthieu M .: Cuando alguien puede falsificar su página web, también puede cambiar la clave pública allí a una donde él mismo conozca la clave privada correspondiente. Por lo tanto, su idea solo ayuda contra los ataques de lectura pasiva, no contra el hombre en el medio.
Paŭlo Ebermann
@Paulo: sí, estoy de acuerdo en que SSL no se trata solo de cifrado, sino también de certificado, desafortunadamente no tomo las decisiones aquí, y cuando la gente dice que quiere usar la página web con una http://conexión regular ... es frustrante: /
Matthieu M.
@Matthieu: ¿Eso significa que está enviando public_key como parte de la página web pública, computando encrypt(entered_password, public_key)en el cliente y enviando ese resultado al servidor, que realiza does_password_match?(user, decrypt(encrypted_password, private_key))?
Ken Bloom
@Ken: más o menos, tienes el cifrado correcto. Para hacer coincidir la contraseña, es más does_password_match(user, salt, decrypt(encrypted, key)), y la sal depende del usuario. Como dije, el problema obvio es la falta de protección del hombre en el medio.
Matthieu M.
52

Eso sugeriría que mantiene las contraseñas en texto abierto, lo cual es un no-no, incluso en escenarios de baja seguridad.

Deberías tener:

if(hash(enteredPassword) == storedHash)

Puede usar hash simple como, por ejemplo, MD5

vartec
fuente
22
+1 para descifrar la contraseña. Pero al menos también agregaría un poco de sal. De lo contrario, dado que los usuarios van a reutilizar nombres de usuario y contraseñas entre sistemas, violar su aplicación de baja seguridad puede permitir que un atacante viole una aplicación de seguridad mucho más alta. El reciente pirateo de HBGary, por ejemplo, logró comprometer el sistema CMS que ejecuta su sitio web y convertirlo en acceso raíz a sus servidores, en parte porque el sistema CMS de baja seguridad no agregaba sal a los hash arstechnica.com/tech-policy/ noticias / 2011/02 /…
Justin Cave
1
De acuerdo ... considere lo siguiente ... "cadenas JavaFile.class | grep -i contraseña"
Bill
¿Cuál es el problema de tener la contraseña en texto sin formato si solo se usan una vez?
10
@Tim porque los usuarios no usarán la contraseña solo una vez. Los estudios muestran consistentemente que los usuarios reutilizan las contraseñas varias veces (por ejemplo, theregister.co.uk/2011/02/10/password_re_use_study ) sin importar cuántas veces se les diga que no lo hagan .
Scott
3
@Tim: además, solo abre tu exe, dll, etc., en un editor de texto, y probablemente verás tu contraseña allí mismo.
Gus Cavalcanti
14

Estoy de acuerdo con aquellos que sugieren el hash, pero también hay una rueda que estás reinventando aquí. Dependiendo de la plataforma, probablemente pueda encontrar una herramienta de gestión de roles / usuarios que cubra todas las cosas de gestión de usuarios de manera segura sin necesidad de mucha intervención de su parte.

glenatron
fuente
Acabo de descubrir proveedores de membresía de ASP.Net pero los estaba mirando pensando "¿cuántas veces he perdido el tiempo implementando algo como esto?"
glenatron
8

La seguridad es un tema muy delicado, particularmente porque debe haber un equilibrio entre incomodar a sus usuarios y asegurarse de que su información esté segura. Por lo general, la fórmula de cuánta seguridad necesita depende de la importancia de los datos. En breve:

isSecuritySufficient = effortToBreak > rewardForBreaking

Un malentendido común sobre las personas que hacen cosas malas es lo que buscan. La mayoría de ellos están fuera para destruir la confianza . Siempre debe hacer todo lo posible para proteger la confianza de sus usuarios. Parte de eso es hacer su debida diligencia para asegurarse de que su identidad esté segura. Puede que les importen menos los datos que almacenan, pero les importa su identidad, incluso en el umbral de seguridad más bajo.

Hay varias opciones de bajo costo (para implementar e impactar al usuario) disponibles. Uno de ellos es descifrar la contraseña como mínimo. Cualquier servicio que almacene algo tan sensible como una contraseña en texto sin formato merece la vergüenza de ser pirateado.

Principios generales para la protección de contraseña

  • Nunca almacene contraseñas en texto plano
  • Hash utilizando una función de hash segura como SHA-1 o incluso SHA-512 (incluso MD5 es demasiado fácil de encontrar un hash coincidente)
  • Use una aplicación de valor de sal. La sal es bytes aleatorios, ya sea agregados a una contraseña para que sea más difícil de adivinar. La sal debe generarse en tiempo de ejecución y usar información sobre la máquina como valor de semilla en lugar de almacenarse y referenciarse de alguna manera.
  • Use un valor de sal específico del usuario. Use esto junto con su aplicación de sal.
  • Cifre todas las solicitudes de autenticación que pasan por una red. Eso significa usar SSL para aplicaciones web.

Dado que usaría SSL para la autenticación, como mínimo desea cifrar todas las páginas que se ocupan también de la cuenta del usuario. Esto permite que se proteja la mayor parte de la identidad del usuario como sea posible.

Una nota sobre la administración de contraseñas : los usuarios olvidarán su contraseña de vez en cuando. Lo peor que puede hacer es enviarles su contraseña en un correo electrónico. Si implementa los principios descritos anteriormente, no podrá hacerlo de todos modos. Es mucho mejor proporcionar una forma de restablecer su contraseña utilizando un enlace enviado a su dirección de correo electrónico registrada. Ese enlace de reinicio tendrá un código de uso único para garantizar que la persona que accede a la página sea ella.

Berin Loritsch
fuente
1
Al principio me sorprendió la idea de la aplicación salt + user salt, pero cuanto más lo pienso, menos convencido estoy. Si usó, digamos, 4 caracteres de sal de aplicación y 4 de sal de usuario, entonces la diferencia entre eso y 8 caracteres de sal de usuario es solo que la mitad de la sal sería idéntica para cada usuario. Parece que sería más seguro aumentar el tamaño de la sal de usuario, en lugar de tener sal de aplicación. Además, si la sal de la aplicación se basa en el hardware, entonces no puede actualizar o cambiar el hardware sin invalidar todas las contraseñas.
David Conrad
El problema es que la sal del usuario está incluida en la fila de la base de datos con la contraseña del usuario. Si una persona mala sabe para qué sirve una sal (y lo sabe), y la ve en la base de datos, entonces sabe cómo descifrarla por completo. Al incluir una parte en la aplicación que se calcula (de la misma manera cada vez que lo recuerde) en lugar de almacenada, hace que sea mucho más difícil descifrar las tablas de usuario. Por supuesto, puede ir un paso más allá y hacer una sal aleatoria pura de 1 parte y una sal calculada de 1 parte, siendo ambas específicas del usuario.
Berin Loritsch
Ah, ya veo, mantenga parte de la sal fuera de la base de datos. Eso tiene sentido. Gracias.
David Conrad
No veo un problema para almacenar la sal por fila, siempre que sea única por fila. Aquí hay un hash: "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91" (SHA256), aquí está la sal: "671254bdf7944f8fa88e6c9913b948ee". ¿Crees que puedes obtener la contraseña? No hay una mesa de arco iris para esa sal (incluso si te dan la sal), estás atrapado forzándolo con fuerza bruta.
Bryan Boettcher
3

Eso está bien a menos que la contraseña se use para otra cosa. Todavía existe el riesgo de que el usuario decida que puede reutilizar la contraseña, por lo que sería aún mejor con:

if(hash(enteredPassword) == hashOfValidPassword)

Si es para usted o para alguien que sabe que la contraseña está almacenada en texto plano, entonces está bien.


fuente
1
Como en el comentario de Justin Cave a la respuesta de vartec, use sal, entonces if (hash (enteredPassword + salt) == hashOfValidSaltedPassword), y tenga en cuenta que +probablemente sea concatenación, no adición. Esto realmente obstaculiza el uso de tablas de arco iris, que son tablas de hashes de contraseñas probables.
David Thornley
Si todo lo que está buscando es un hash, ¿no podrían simplemente pasar por un bucle de posibles cadenas hasta que uno genere el mismo hash que el hash almacenado? Hay muchas cadenas que podrían corresponder al mismo hash, después de todo.
Morgan Herlocker
@Prof Plum: es muy difícil encontrar colisiones si el algoritmo de hash es bueno. Esta es la base de la criptografía moderna: son esencialmente funciones unidireccionales.
3

¿Está disponible el código fuente? Incluso si no, estoy bastante seguro de que la contraseña se puede encontrar en las instrucciones de la máquina en caso de que el binario esté disponible. Recomendaría hacer una suma de comprobación y comparar eso en su lugar.

Nunca pase por alto la seguridad, incluso si no es muy importante en su opinión.

Anto
fuente
2
Sí, mala idea si es un proyecto de código abierto :)
-1 - Si crees que tener la fuente hace la diferencia, no sabes nada sobre seguridad.
mattnz
1

Absolutamente no. Eche un vistazo a esto , describe cómo los hackers piratearon un sitio web de seguridad. Tu plan te tendría como el eslabón más débil de la cadena.

Dave
fuente
0

Se ha observado en un par de respuestas que no debe almacenar la contraseña en sí, sino un hash, y debe usar SSL.

Usted puede decir, ¿cuál es el gran problema? Si mi aplicación es pirateada, eso es de poca preocupación. Bueno, es un patrón bastante común para los usuarios reutilizar la misma contraseña en todos los sitios. Si un hacker piratea su sitio y obtiene acceso a las contraseñas de los usuarios, el hacker podría hacerse pasar por muchos de esos usuarios en otros sitios de mayor importancia para esos usuarios. Por lo tanto, piratear su sitio podría ser el primer paso para que un hacker obtenga acceso a la información bancaria de los usuarios.

Y simplemente descifrar la contraseña no es suficiente. Necesitas picadillo con sal. Los hackers tienen tablas de búsqueda de hash inverso, por lo que para un hash determinado, pueden encontrar una contraseña coincidente.

Si elige no implementar esta función, debe informar a los usuarios de esta falta de seguridad, alentándolos a que no usen la misma contraseña que usan en otros lugares.

Pete
fuente
-2

Mientras este sea el lado del servidor ... Entonces sí.

Si desea un poco más de seguridad, vaya a https y cifre \ hash la contraseña en la base de datos.

Imbéciles
fuente
3
¿Por qué asumir que esta es una aplicación web?
Chris
¡Buen punto! Lo acabo de hacer.
Morons
44
-1 incluso si es del lado del servidor, todavía no está bien.
GSto