Pregunta

Autenticación basada en formularios para sitios web

Creemos que Stack Overflow no debería ser solo un recurso para preguntas técnicas muy específicas, sino también para pautas generales sobre cómo resolver variaciones de problemas comunes.La "autenticación basada en formularios para sitios web" debería ser un buen tema para tal experimento.

Debe incluir temas como:

  • Cómo iniciar sesión
  • Cómo cerrar sesión
  • Cómo permanecer conectado
  • Gestión de cookies (incluidas las configuraciones recomendadas)
  • Cifrado SSL/HTTPS
  • Cómo almacenar contraseñas
  • Usando preguntas secretas
  • Funcionalidad de nombre de usuario/contraseña olvidada
  • Uso de nonces para prevenir falsificaciones de solicitudes entre sitios (CSRF)
  • ID abierto
  • Casilla de verificación "Recuérdame"
  • Autocompletado del navegador de nombres de usuario y contraseñas
  • URL secretas (públicas URL protegido por digestión)
  • Comprobando la seguridad de la contraseña
  • Validación de correo electrónico
  • y mucho más sobre autenticación basada en formularios...

No debe incluir cosas como:

  • Roles y autorización
  • Autenticación básica HTTP

Por favor ayúdanos a:

  1. Sugerir subtemas
  2. Enviar buenos artículos sobre este tema.
  3. Editando la respuesta oficial
¿Fue útil?

Solución

PARTE I:Cómo iniciar sesión

Asumiremos que ya sabe cómo crear un formulario HTML de inicio de sesión y contraseña que envía los valores a un script en el lado del servidor para la autenticación.Las secciones siguientes tratarán patrones para una autenticación práctica sólida y cómo evitar los errores de seguridad más comunes.

¿A HTTPS o no a HTTPS?

A menos que la conexión ya sea segura (es decir, tunelizada a través de HTTPS usando SSL/TLS), los valores de su formulario de inicio de sesión se enviarán en texto sin cifrar, lo que permite que cualquier persona que escuche la línea entre el navegador y el servidor web pueda leer los inicios de sesión a medida que pasan. a través de.Este tipo de escuchas telefónicas las realizan de forma rutinaria los gobiernos, pero en general, no nos ocuparemos de los cables "propios" más que para decir lo siguiente:Si está protegiendo algo importante, utilice HTTPS.

En esencia, el único práctico Una forma de protegerse contra escuchas telefónicas/rastreo de paquetes durante el inicio de sesión es mediante el uso de HTTPS u otro esquema de cifrado basado en certificados (por ejemplo, TLS) o un esquema de desafío-respuesta probado y probado (por ejemplo, el Diffie-Hellman-basado en SRP). Cualquier otro método se puede eludir fácilmente. por un atacante que escucha a escondidas.

Por supuesto, si está dispuesto a ser un poco poco práctico, también puede emplear algún tipo de esquema de autenticación de dos factores (p. ej.la aplicación Google Authenticator, un libro de códigos físico estilo "guerra fría" o un dongle generador de claves RSA).Si se aplica correctamente, esto podría funcionar incluso con una conexión no segura, pero es difícil imaginar que un desarrollador esté dispuesto a implementar la autenticación de dos factores pero no SSL.

(No) implementar cifrado/hashing de JavaScript propio

Dado el costo distinto de cero y la dificultad técnica percibida de configurar un certificado SSL en su sitio web, algunos desarrolladores se sienten tentados a implementar sus propios esquemas de cifrado o hash en el navegador para evitar pasar inicios de sesión en texto sin cifrar a través de un cable no seguro.

Si bien este es un pensamiento noble, es esencialmente inútil (y puede ser una falla de seguridad) a menos que se combine con uno de los anteriores, es decir, proteger la línea con un cifrado seguro o utilizar un mecanismo de desafío-respuesta probado (si no sabe qué es eso, sepa que es uno de los conceptos más difíciles de probar, más difíciles de diseñar y más difíciles de implementar en seguridad digital).

Si bien es cierto que el hash de la contraseña puede ser eficaz contra divulgación de contraseña, es vulnerable a ataques de repetición, ataques/secuestros de tipo Man-In-The-Middle (si un atacante puede inyectar unos pocos bytes en su página HTML no segura antes de que llegue a su navegador, simplemente puede comentar el hash en JavaScript), o ataques de fuerza bruta (ya que le está entregando al atacante nombre de usuario, sal y contraseña hash).

CAPTCHAS contra la humanidad

CAPTCHA está destinado a frustrar una categoría específica de ataque:Diccionario automatizado/prueba y error de fuerza bruta sin operador humano.No hay duda de que se trata de una amenaza real; sin embargo, hay formas de abordarla sin problemas que no requieren un CAPTCHA, esquemas de limitación de inicio de sesión del lado del servidor específicamente diseñados adecuadamente; los analizaremos más adelante.

Sepa que las implementaciones de CAPTCHA no se crean de la misma manera;a menudo no tienen solución humana, la mayoría de ellos son en realidad ineficaces contra los robots, todos ellos son ineficaces contra la mano de obra barata del tercer mundo (según OWASP, la tarifa actual de explotación es de $12 por 500 pruebas), y algunas implementaciones pueden ser técnicamente ilegales en algunos países (ver Hoja de referencia de autenticación OWASP).Si debe utilizar un CAPTCHA, utilice el de Google reCAPTCHA, ya que es compatible con OCR por definición (ya que utiliza escaneos de libros ya clasificados erróneamente con OCR) y se esfuerza mucho por ser fácil de usar.

Personalmente, tiendo a encontrar CAPTCHAS molestos y los uso solo como último recurso cuando un usuario no ha podido iniciar sesión varias veces y los retrasos en la limitación están al máximo.Esto sucederá en raras ocasiones como para que sea aceptable y fortalece el sistema en su conjunto.

Almacenamiento de contraseñas/verificación de inicios de sesión

Esto finalmente puede ser de conocimiento común después de todos los hacks y filtraciones de datos de usuarios muy publicitados que hemos visto en los últimos años, pero hay que decirlo:No almacene contraseñas en texto sin cifrar en su base de datos.Las bases de datos de los usuarios son rutinariamente pirateadas, filtradas o obtenidas mediante inyección SQL, y si está almacenando contraseñas en texto plano y sin formato, se acabó instantáneamente el juego para su seguridad de inicio de sesión.

Entonces, si no puede almacenar la contraseña, ¿cómo verifica que la combinación de inicio de sesión y contraseña publicada en el formulario de inicio de sesión sea correcta?La respuesta es hash usando un función de derivación de claves.Cada vez que se crea un nuevo usuario o se cambia una contraseña, usted toma la contraseña y la ejecuta a través de un KDF, como Argon2, bcrypt, scrypt o PBKDF2, convirtiendo la contraseña de texto sin cifrar ("correcthorsebatterystaple") en una cadena larga y de apariencia aleatoria. , que es mucho más seguro de almacenar en su base de datos.Para verificar un inicio de sesión, ejecuta la misma función hash en la contraseña ingresada, esta vez pasando el salt y compara la cadena hash resultante con el valor almacenado en su base de datos.Argon2, bcrypt y scrypt ya almacenan la sal con el hash.Mira esto artículo en sec.stackexchange para obtener información más detallada.

La razón por la que se utiliza una sal es que el hash en sí mismo no es suficiente; querrás agregar la llamada "sal" para proteger el hash contra mesas arcoiris.Una sal evita eficazmente que dos contraseñas que coincidan exactamente se almacenen con el mismo valor hash, lo que evita que se escanee toda la base de datos en una sola ejecución si un atacante está ejecutando un ataque de adivinación de contraseña.

No se debe utilizar un hash criptográfico para el almacenamiento de contraseñas porque las contraseñas seleccionadas por el usuario no son lo suficientemente seguras (es decir,normalmente no contienen suficiente entropía) y un atacante con acceso a los hashes podría completar un ataque de adivinación de contraseña en un tiempo relativamente corto.Por eso se utilizan los KDF: estos son eficaces "estirar la llave", lo que significa que cada contraseña que adivina un atacante provoca múltiples repeticiones del algoritmo hash, por ejemplo 10.000 veces, lo que hace que el atacante adivine la contraseña 10.000 veces más lento.

Datos de sesión: "Ha iniciado sesión como Spiderman69"

Una vez que el servidor ha verificado el nombre de usuario y la contraseña con su base de datos de usuario y ha encontrado una coincidencia, el sistema necesita una forma de recordar que el navegador ha sido autenticado.Este hecho sólo debería almacenarse en el lado del servidor en los datos de la sesión.

Si no está familiarizado con los datos de la sesión, así es como funciona:Una única cadena generada aleatoriamente se almacena en una cookie que expira y se utiliza para hacer referencia a una colección de datos (los datos de la sesión) que se almacenan en el servidor.Si está utilizando un marco MVC, esto sin duda ya está solucionado.

Si es posible, asegúrese de que la cookie de sesión tenga configurados los indicadores de seguridad y Solo HTTP cuando se envíe al navegador.El indicador HttpOnly proporciona cierta protección contra la lectura de la cookie mediante un ataque XSS.La bandera segura garantiza que la cookie solo se devuelva a través de HTTPS y, por lo tanto, protege contra ataques de rastreo de red.El valor de la cookie no debería ser predecible.Cuando se presenta una cookie que hace referencia a una sesión inexistente, su valor debe reemplazarse inmediatamente para evitar fijación de sesión.

PARTE II:Cómo permanecer conectado: la infame casilla de verificación "Recordarme"

Las cookies de inicio de sesión persistentes (función "recordarme") son una zona de peligro;por un lado, son tan seguros como los inicios de sesión convencionales cuando los usuarios saben cómo manejarlos;y, por otro lado, suponen un enorme riesgo para la seguridad en manos de usuarios descuidados, que pueden utilizarlas en ordenadores públicos y olvidarse de cerrar sesión, y que pueden no saber qué son las cookies del navegador o cómo eliminarlas.

Personalmente, me gustan los inicios de sesión persistentes en los sitios web que visito regularmente, pero sé cómo manejarlos de forma segura.Si está seguro de que sus usuarios saben lo mismo, puede utilizar inicios de sesión persistentes con la conciencia tranquila.Si no, bueno, entonces puedes suscribirte a la filosofía de que los usuarios que son descuidados con sus credenciales de inicio de sesión se lo provocan a sí mismos si son pirateados.Tampoco es que vayamos a las casas de nuestros usuarios y arranquemos todas esas notas Post-It con contraseñas que tienen alineadas en el borde de sus monitores.

Por supuesto, algunos sistemas no pueden darse el lujo de tener cualquier cuentas pirateadas;para tales sistemas, no hay manera de justificar el hecho de tener inicios de sesión persistentes.

Si decide implementar cookies de inicio de sesión persistentes, así es como lo hace:

  1. Primero, tómate un tiempo para leer. Artículo de la Iniciativa Paragon sobre el tema.Necesitará acertar con varios elementos y el artículo explica muy bien cada uno de ellos.

  2. Y sólo para reiterar uno de los errores más comunes, NO ALMACENE LA COOKIE (TOKEN) DE INICIO DE SESIÓN PERSISTENTE EN SU BASE DE DATOS, ¡SÓLO UN HASH DE ELLA! El token de inicio de sesión es equivalente a una contraseña, por lo que si un atacante tiene en sus manos su base de datos, podría usar los tokens para iniciar sesión en cualquier cuenta, como si fueran combinaciones de texto sin cifrar de inicio de sesión y contraseña.Por lo tanto, utilice hash (según https://security.stackexchange.com/a/63438/5002 un hash débil funcionará bien para este propósito) al almacenar tokens de inicio de sesión persistentes.

PARTE III:Usar preguntas secretas

No implementes 'preguntas secretas'.La función de "preguntas secretas" es un antipatrón de seguridad.Lea el artículo desde el enlace número 4 de la lista DE DEBE LEER.Puedes preguntarle a Sarah Palin sobre eso, después de su Yahoo!Su cuenta de correo electrónico fue pirateada durante una campaña presidencial anterior porque la respuesta a su pregunta de seguridad era...¡"Escuela secundaria Wasilla"!

Incluso con las preguntas especificadas por el usuario, es muy probable que la mayoría de los usuarios elijan una de las siguientes opciones:

  • Una pregunta secreta "estándar" como el apellido de soltera de la madre o su mascota favorita

  • Una simple trivia que cualquiera podría extraer de su blog, perfil de LinkedIn o similar.

  • Cualquier pregunta que sea más fácil de responder que adivinar su contraseña.Que, para cualquier contraseña decente, son todas las preguntas que puedas imaginar.

En conclusión, las preguntas de seguridad son inherentemente inseguras en prácticamente todas sus formas y variaciones, y no deberían emplearse en un esquema de autenticación por ningún motivo.

La verdadera razón por la que las preguntas de seguridad existen es que convenientemente ahorran el costo de algunas llamadas de soporte de usuarios que no pueden acceder a su correo electrónico para obtener un código de reactivación.Esto a expensas de la seguridad y la reputación de Sarah Palin.¿Vale la pena?Probablemente no.

PARTE IV:Funcionalidad de contraseña olvidada

Ya mencioné por qué deberías nunca uses preguntas de seguridad para manejar contraseñas de usuario olvidadas/perdidas;Tampoco hace falta decir que nunca debe enviar por correo electrónico a los usuarios sus contraseñas reales.Hay al menos dos errores más comunes que se deben evitar en este campo:

  1. No reiniciar una contraseña olvidada a una contraseña segura generada automáticamente (tales contraseñas son notoriamente difíciles de recordar, lo que significa que el usuario debe cambiarla o escribirla), por ejemplo, en un Post-It amarillo brillante en el borde de su monitor.En lugar de establecer una nueva contraseña, simplemente permita que los usuarios elijan una nueva de inmediato, que es lo que quieren hacer de todos modos.(Una excepción a esto podría ser si los usuarios utilizan universalmente un administrador de contraseñas para almacenar/administrar contraseñas que normalmente serían imposibles de recordar sin escribirlas).

  2. Siempre haga un hash del código/token de contraseña perdido en la base de datos. DE NUEVO, este código es otro ejemplo de equivalente de contraseña, por lo que DEBE tener un hash en caso de que un atacante tenga acceso a su base de datos.Cuando se solicita un código de contraseña perdido, envíe el código de texto sin formato a la dirección de correo electrónico del usuario, luego haga un hash, guarde el hash en su base de datos y tirar el original.Como una contraseña o un token de inicio de sesión persistente.

Una nota final:Asegúrese siempre de que su interfaz para ingresar el 'código de contraseña perdido' sea al menos tan segura como su formulario de inicio de sesión, o un atacante simplemente lo usará para obtener acceso.Asegurarse de generar 'códigos de contraseña perdidos' muy largos (por ejemplo, 16 caracteres alfanuméricos que distinguen entre mayúsculas y minúsculas) es un buen comienzo, pero considere agregar el mismo esquema de limitación que utiliza para el formulario de inicio de sesión.

PARTE V:Comprobar la seguridad de la contraseña

Primero, querrás leer este pequeño artículo para comprobar la realidad: Las 500 contraseñas más comunes

Bien, tal vez la lista no sea la canónico lista de contraseñas más comunes en cualquier sistema en cualquier lugar, pero es un buen indicador de cuán mal elegirán las personas sus contraseñas cuando no existe una política implementada.Además, la lista parece terriblemente cercana cuando la comparas con análisis disponibles públicamente de contraseñas robadas recientemente.

Entonces:Sin requisitos mínimos de seguridad de contraseña, el 2% de los usuarios utiliza una de las 20 contraseñas más comunes.Significado:Si un atacante consigue sólo 20 intentos, 1 de cada 50 cuentas de su sitio web será crackeable.

Para frustrar esto es necesario calcular la entropía de una contraseña y luego aplicar un umbral.El Instituto Nacional de Estándares y Tecnología (NIST) Publicación especial 800-63 tiene un conjunto de muy buenas sugerencias.Eso, cuando se combina con un diccionario y un análisis de la distribución del teclado (por ejemplo, 'qwertyuiop' es una contraseña incorrecta), puede rechazar el 99% de todas las contraseñas mal seleccionadas a un nivel de 18 bits de entropía.Simplemente calculando la seguridad de la contraseña y mostrando un medidor de fuerza visual a un usuario es bueno, pero insuficiente.A menos que se aplique, lo más probable es que muchos usuarios lo ignoren.

Y para una visión refrescante de la facilidad de uso de las contraseñas de alta entropía, Randall Munroe Seguridad de la contraseña xkcd Es muy recomendable.

Utilice Troy Hunt ¿Me han engañado API? para comparar las contraseñas de los usuarios con las contraseñas comprometidas en violaciones de datos públicos.

PARTE VI:Mucho más - O:Prevención de intentos de inicio de sesión rápidos

Primero, eche un vistazo a los números: Velocidades de recuperación de contraseña: ¿cuánto tiempo permanecerá vigente su contraseña?

Si no tiene tiempo para revisar las tablas en ese enlace, aquí está la lista de ellas:

  1. Se necesita prácticamente sin tiempo para descifrar una contraseña débil, incluso si la estás descifrando con un ábaco

  2. Se necesita prácticamente sin tiempo para descifrar una contraseña alfanumérica de 9 caracteres si es no distingue entre mayúsculas y minúsculas

  3. Se necesita prácticamente sin tiempo para descifrar una contraseña compleja, con símbolos, letras y números, en mayúsculas y minúsculas, si es menos de 8 caracteres (una PC de escritorio puede buscar en todo el espacio de claves hasta 7 caracteres en cuestión de días o incluso horas)

  4. Sin embargo, tomaría una cantidad excesiva de tiempo descifrar incluso una contraseña de 6 caracteres. ¡Si estuvieras limitado a un intento por segundo!

Entonces, ¿qué podemos aprender de estos números?Bueno, muchas, pero podemos centrarnos en la parte más importante:el hecho de que evitar un gran número de intentos de inicio de sesión sucesivos y rápidos (es decir,el fuerza bruta ataque) realmente no es tan difícil.Pero prevenirlo bien No es tan fácil como parece.

En términos generales, tienes tres opciones y todas ellas son efectivas contra ataques de fuerza bruta. (y ataques de diccionario, pero como ya estás empleando una política de contraseñas seguras, no deberían ser un problema):

  • Presentar un CAPTCHA después de N intentos fallidos (muy molesto y a menudo ineficaz, pero me repito aquí)

  • Bloquear cuentas y requerir verificación por correo electrónico después de N intentos fallidos (este es un DoS ataque esperando a suceder)

  • Y finalmente, limitación de inicio de sesión:es decir, establecer un retraso de tiempo entre intentos después de N intentos fallidos (sí, los ataques DoS todavía son posibles, pero al menos son mucho menos probables y mucho más complicados de realizar).

Mejor práctica n.° 1: Un breve retraso que aumenta con el número de intentos fallidos, como:

  • 1 intento fallido = sin demora
  • 2 intentos fallidos = retraso de 2 segundos
  • 3 intentos fallidos = retraso de 4 segundos
  • 4 intentos fallidos = retraso de 8 segundos
  • 5 intentos fallidos = retraso de 16 segundos
  • etc.

Atacar DoS a este esquema sería muy poco práctico, ya que el tiempo de bloqueo resultante es ligeramente mayor que la suma de los tiempos de bloqueo anteriores.

Para aclarar:El retraso es no un retraso antes de devolver la respuesta al navegador.Es más bien un tiempo de espera o un período refractario durante el cual los intentos de inicio de sesión en una cuenta específica o desde una dirección IP específica no serán aceptados ni evaluados en absoluto.Es decir, las credenciales correctas no volverán a aparecer en un inicio de sesión exitoso y las credenciales incorrectas no provocarán un aumento de la demora.

Mejor práctica n.° 2: Un retraso de duración media que entra en vigor después de N intentos fallidos, como:

  • 1-4 intentos fallidos = sin demora
  • 5 intentos fallidos = retraso de 15 a 30 minutos

Atacar DoS este esquema sería bastante poco práctico, pero ciertamente factible.Además, puede resultar relevante tener en cuenta que una demora tan larga puede resultar muy molesta para un usuario legítimo.A los usuarios olvidadizos no les agradarás.

Mejor práctica n.° 3: Combinando los dos enfoques, ya sea un retraso breve y fijo que entra en vigor después de N intentos fallidos, como:

  • 1-4 intentos fallidos = sin demora
  • Más de 5 intentos fallidos = retraso de 20 segundos

O un retraso creciente con un límite superior fijo, como:

  • 1 intento fallido = retraso de 5 segundos
  • 2 intentos fallidos = retraso de 15 segundos
  • 3+ intentos fallidos = retraso de 45 segundos

Este esquema final fue tomado de las sugerencias de mejores prácticas de OWASP (enlace 1 de la lista DEBE LEER) y debe considerarse una mejor práctica, incluso si es cierto que es restrictiva.

Sin embargo, como regla general, diría:cuanto más sólida sea su política de contraseñas, menos tendrá que molestar a los usuarios con retrasos.Si necesita contraseñas seguras (alfanuméricas que distingan entre mayúsculas y minúsculas + números y símbolos requeridos) de más de 9 caracteres, puede darles a los usuarios de 2 a 4 intentos de contraseña no demorados antes de activar la limitación.

DoS atacaría este esquema final de limitación de inicio de sesión. muy poco práctico.Y como toque final, permita siempre el paso de inicios de sesión persistentes (cookies) (y/o un formulario de inicio de sesión verificado por CAPTCHA), para que los usuarios legítimos ni siquiera sufran demoras. mientras el ataque está en progreso.De esta manera, el poco práctico ataque DoS se convierte en un extremadamente ataque poco práctico.

Además, tiene sentido aplicar limitaciones más agresivas a las cuentas de administrador, ya que esos son los puntos de entrada más atractivos.

PARTE VII:Ataques distribuidos de fuerza bruta

Además, los atacantes más avanzados intentarán eludir la limitación de inicio de sesión "difundiendo sus actividades":

  • Distribuir los intentos en una botnet para evitar que se marquen direcciones IP

  • En lugar de elegir un usuario y probar las 50.000 contraseñas más comunes (lo cual no pueden debido a nuestra limitación), elegirán LA contraseña más común y la probarán con 50.000 usuarios.De esa manera, no solo evitan medidas de intentos máximos como CAPTCHA y limitación de inicio de sesión, sino que también aumentan sus posibilidades de éxito, ya que la contraseña número 1 más común es mucho más probable que la número 49,995.

  • Espaciar las solicitudes de inicio de sesión para cada cuenta de usuario, digamos, con 30 segundos de diferencia, para pasar desapercibido

En este caso, la mejor práctica sería registrar el número de inicios de sesión fallidos, en todo el sistema, y utilizar un promedio móvil de la frecuencia de inicios de sesión incorrectos de su sitio como base para un límite superior que luego impone a todos los usuarios.

¿Demasiado abstracto?Déjame reformular:

Digamos que su sitio ha tenido un promedio de 120 inicios de sesión incorrectos por día durante los últimos 3 meses.Usando eso (promedio móvil), su sistema podría establecer el límite global en 3 veces eso, es decir.360 intentos fallidos en un período de 24 horas.Luego, si el número total de intentos fallidos en todas las cuentas excede ese número en un día (o mejor aún, monitorea la velocidad de aceleración y activa un umbral calculado), se activa la limitación de inicio de sesión en todo el sistema, lo que significa breves retrasos para TODOS los usuarios. (aún así, con la excepción de los inicios de sesión mediante cookies y/o los inicios de sesión CAPTCHA de respaldo).

También publiqué una pregunta con más detalles y una muy buena discusión sobre cómo evitar trampas difíciles para defenderse de ataques distribuidos de fuerza bruta

PARTE VIII:Autenticación de dos factores y proveedores de autenticación

Las credenciales pueden verse comprometidas, ya sea por exploits, contraseñas escritas y perdidas, portátiles con llaves robadas o usuarios que inician sesión en sitios de phishing.Los inicios de sesión se pueden proteger aún más con la autenticación de dos factores, que utiliza factores fuera de banda, como códigos de un solo uso recibidos de una llamada telefónica, mensaje SMS, aplicación o dongle.Varios proveedores ofrecen servicios de autenticación de dos factores.

La autenticación se puede delegar completamente a un servicio de inicio de sesión único, donde otro proveedor se encarga de recopilar las credenciales.Esto lleva el problema a un tercero de confianza.Google y Twitter ofrecen servicios SSO basados ​​en estándares, mientras que Facebook ofrece una solución patentada similar.

ENLACES QUE DEBE LEER Sobre la autenticación web

  1. Guía OWASP para la autenticación / Hoja de referencia de autenticación OWASP
  2. Lo que se debe y no se debe hacer en la autenticación de clientes en la Web (artículo de investigación del MIT muy legible)
  3. Wikipedia:galleta HTTP
  4. Preguntas de conocimiento personal para la autenticación alternativa:Cuestiones de seguridad en la era de Facebook (artículo de investigación de Berkeley muy legible)

Otros consejos

Artículo definitivo

Enviando credenciales

La única forma práctica de enviar credenciales de forma 100% segura es mediante el uso SSL.Usar JavaScript para codificar la contraseña no es seguro.Errores comunes del hash de contraseñas del lado del cliente:

  • Si la conexión entre el cliente y el servidor no está cifrada, todo lo que haga es vulnerable a ataques de intermediario.Un atacante podría reemplazar el javascript entrante para romper el hash o enviar todas las credenciales a su servidor, podría escuchar las respuestas de los clientes y hacerse pasar por los usuarios perfectamente, etc.etc.SSL con autoridades certificadoras confiables está diseñado para prevenir ataques MitM.
  • La contraseña hash recibida por el servidor es menos seguro si no realiza trabajo adicional y redundante en el servidor.

Hay otro método seguro llamado SRP, pero está patentado (aunque es licencia gratuita) y hay pocas buenas implementaciones disponibles.

Almacenamiento de contraseñas

Nunca almacene contraseñas como texto sin formato en la base de datos.Incluso si no te importa la seguridad de tu propio sitio.Supongamos que algunos de sus usuarios reutilizarán la contraseña de su cuenta bancaria en línea.Por lo tanto, almacene la contraseña hash y deseche la original.Y asegúrese de que la contraseña no aparezca en los registros de acceso o de aplicaciones.OWASP recomienda el uso de Argon2 como su primera opción para nuevas aplicaciones.Si no está disponible, se debe utilizar PBKDF2 o scrypt.Y finalmente, si ninguno de los anteriores está disponible, utilice bcrypt.

Los hashes por sí solos también son inseguros.Por ejemplo, contraseñas idénticas significan hashes idénticos; esto hace que las tablas de búsqueda de hash sean una forma eficaz de descifrar muchas contraseñas a la vez.En su lugar, almacene el salado picadillo.Un salt es una cadena agregada a la contraseña antes del hash; use un salt diferente (aleatorio) por usuario.La sal es un valor público, por lo que puedes almacenarlos con el hash en la base de datos.Ver aquí para más información sobre esto.

Esto significa que no puedes enviarle al usuario sus contraseñas olvidadas (porque solo tienes el hash).No restablezca la contraseña del usuario a menos que lo haya autenticado (los usuarios deben demostrar que pueden leer los correos electrónicos enviados a la dirección de correo electrónico almacenada (y validada).

Preguntas de seguridad

Las preguntas de seguridad son inseguras; evite usarlas.¿Por qué?Cualquier cosa que haga una pregunta de seguridad, una contraseña lo hace mejor.Leer PARTE III:Usar preguntas secretas en @Jens Roland respuesta aquí en esta wiki.

Cookies de sesión

Después de que el usuario inicia sesión, el servidor le envía una cookie de sesión.El servidor puede recuperar el nombre de usuario o la identificación de la cookie, pero nadie más puede generar dicha cookie (TODO explica los mecanismos).

Las cookies pueden ser secuestradas:son tan seguros como el resto de la máquina del cliente y otras comunicaciones.Se pueden leer desde el disco, rastrear el tráfico de la red, eliminarlos mediante un ataque de secuencias de comandos entre sitios, realizar phishing desde un DNS envenenado para que el cliente envíe sus cookies a los servidores equivocados.No envíe cookies persistentes.Las cookies deben caducar al final de la sesión del cliente (el navegador se cierra o sale de su dominio).

Si desea que sus usuarios inicien sesión automáticamente, puede configurar una cookie persistente, pero debe ser distinta de una cookie de sesión completa.Puede establecer un indicador adicional de que el usuario ha iniciado sesión automáticamente y necesita iniciar sesión de verdad para operaciones confidenciales.Esto es popular entre los sitios de compras que desean brindarle una experiencia de compra personalizada y fluida, pero aún así proteger sus datos financieros.Por ejemplo, cuando vuelves a visitar Amazon, te muestran una página en la que parece que has iniciado sesión, pero cuando vas a realizar un pedido (o cambias tu dirección de envío, tarjeta de crédito, etc.), te piden que confirmes. tu contraseña.

Los sitios web financieros, como bancos y tarjetas de crédito, por otro lado, sólo contienen datos confidenciales y no deberían permitir el inicio de sesión automático ni un modo de baja seguridad.

Lista de recursos externos

Primero, una fuerte advertencia de que esta respuesta no es la más adecuada para esta pregunta exacta.¡Definitivamente no debería ser la mejor respuesta!

Seguiré adelante y mencionaré la propuesta de Mozilla. ID del navegador (o quizás más precisamente, el Protocolo de correo electrónico verificado) con el ánimo de encontrar una vía de actualización para mejorar los enfoques de autenticación en el futuro.

Lo resumiré de esta manera:

  1. Mozilla es una organización sin fines de lucro con valores que se alinean bien con la búsqueda de buenas soluciones a este problema.
  2. La realidad actual es que la mayoría de los sitios web utilizan autenticación basada en formularios.
  3. La autenticación basada en formularios tiene un gran inconveniente, que es un mayor riesgo de suplantación de identidad.Se solicita a los usuarios que ingresen información confidencial en un área controlada por una entidad remota, en lugar de un área controlada por su Agente de usuario (navegador).
  4. Dado que los navegadores son implícitamente confiables (la idea de un Agente de Usuario es actuar en nombre del Usuario), pueden ayudar a mejorar esta situación.
  5. La fuerza principal que frena el progreso aquí es punto muerto en el despliegue.Las soluciones deben descomponerse en pasos que proporcionen algún beneficio incremental por sí solos.
  6. El método descentralizado más simple para expresar una identidad integrada en la infraestructura de Internet es el nombre de dominio.
  7. Como segundo nivel de expresión de identidad, cada dominio gestiona su propio conjunto de cuentas.
  8. El formulario “cuenta@dominio” es conciso y está respaldado por una amplia gama de protocolos y esquemas de URI.Por supuesto, un identificador de este tipo se reconoce más universalmente como una dirección de correo electrónico.
  9. Los proveedores de correo electrónico ya son de facto los principales proveedores de identidad en línea.Los flujos de restablecimiento de contraseña actuales generalmente le permiten tomar el control de una cuenta si puede demostrar que controla la dirección de correo electrónico asociada a esa cuenta.
  10. El Protocolo de correo electrónico verificado se propuso para proporcionar un método seguro, basado en criptografía de clave pública, para agilizar el proceso de demostrarle al dominio B que tiene una cuenta en el dominio A.
  11. Para los navegadores que no admiten el protocolo de correo electrónico verificado (actualmente todos), Mozilla proporciona una corrección que implementa el protocolo en el código JavaScript del lado del cliente.
  12. Para los servicios de correo electrónico que no admiten el Protocolo de correo electrónico verificado, el protocolo permite a terceros actuar como intermediarios confiables, afirmando que han verificado la propiedad de una cuenta por parte de un usuario.No es deseable tener un gran número de terceros de este tipo;esta capacidad está destinada únicamente a permitir una ruta de actualización y es mucho más preferible que los servicios de correo electrónico proporcionen estas afirmaciones por sí mismos.
  13. Mozilla ofrece su propio servicio para actuar como un tercero de confianza.Los proveedores de servicios (es decir, las partes que confían) que implementan el protocolo de correo electrónico verificado pueden optar por confiar o no en las afirmaciones de Mozilla.El servicio de Mozilla verifica la propiedad de la cuenta de los usuarios mediante el medio convencional de enviar un correo electrónico con un enlace de confirmación.
  14. Por supuesto, los proveedores de servicios pueden ofrecer este protocolo como una opción además de cualquier otro método de autenticación que deseen ofrecer.
  15. Un gran beneficio de la interfaz de usuario que se busca aquí es el "selector de identidad".Cuando un usuario visita un sitio y elige autenticarse, su navegador le muestra una selección de direcciones de correo electrónico ("personal", "trabajo", "activismo político", etc.) que puede utilizar para identificarse en el sitio.
  16. Otro gran beneficio de la interfaz de usuario que se busca como parte de este esfuerzo es ayudar al navegador a saber más sobre la sesión del usuario – con quién iniciaron sesión actualmente, principalmente, por lo que puede mostrarlo en el navegador Chrome.
  17. Debido a la naturaleza distribuida de este sistema, evita el bloqueo a sitios importantes como Facebook, Twitter, Google, etc.Cualquier individuo puede ser propietario de su propio dominio y, por tanto, actuar como su propio proveedor de identidad.

Esto no es estrictamente una "autenticación basada en formularios para sitios web".Pero es un esfuerzo por pasar de la norma actual de autenticación basada en formularios a algo más seguro:autenticación compatible con el navegador.

Simplemente pensé en compartir esta solución que encontré que funciona bien.

yo lo llamo el Campo ficticio (aunque no he inventado esto, así que no me den crédito).

En breve:sólo tienes que insertar esto en tu <form> y verifique que esté vacío al validar:

<input type="text" name="email" style="display:none" />

El truco consiste en engañar a un bot haciéndole creer que tiene que insertar datos en un campo obligatorio, por eso llamé a la entrada "correo electrónico".Si ya tiene un campo llamado correo electrónico que está utilizando, debería intentar nombrar el campo ficticio con otro nombre como "empresa", "teléfono" o "dirección de correo electrónico".Simplemente elija algo que sepa que no necesita y que parezca algo que la gente normalmente encontraría lógico para completar en un formulario web.Ahora esconde el input campo usando CSS o JavaScript/jQuery, lo que mejor se adapte a sus necesidades, simplemente no establecer la entrada type a hidden De lo contrario, el robot no se dejará engañar.

Cuando esté validando el formulario (ya sea del lado del cliente o del servidor), verifique si su campo ficticio se ha completado para determinar si fue enviado por un humano o un robot.

Ejemplo:

En el caso de un humano:El usuario no verá el campo ficticio (en mi caso llamado "correo electrónico") y no intentará completarlo.Por lo tanto, el valor del campo ficticio aún debería estar vacío cuando se haya enviado el formulario.

En caso de un robot: El bot verá un campo cuyo tipo es text y un nombre email (o como sea que lo llames) y lógicamente intentará llenarlo con los datos apropiados.No importa si diseñó el formulario de entrada con algún CSS elegante, los desarrolladores web lo hacen todo el tiempo.Cualquiera que sea el valor en el campo ficticio, no nos importa siempre que sea mayor que 0 caracteres.

Utilicé este método en un libro de visitas en combinación con CAPTCHA, y no he visto ni una sola publicación de spam desde entonces.Había usado una solución solo CAPTCHA antes, pero finalmente resultó en aproximadamente cinco publicaciones de spam cada hora.Agregar el campo ficticio en el formulario ha impedido (al menos hasta ahora) que aparezca todo el spam.

Creo que esto también se puede usar bien con un formulario de inicio de sesión/autenticación.

Advertencia:Por supuesto, este método no es 100% infalible.Los bots se pueden programar para ignorar los campos de entrada con el estilo display:none aplicado a ello.También debe pensar en las personas que utilizan alguna forma de autocompletar (¡como la que la mayoría de los navegadores tienen incorporada!) para completar automáticamente todos los campos del formulario.También podrían elegir un campo ficticio.

También puedes variar esto un poco dejando el campo ficticio visible pero fuera de los límites de la pantalla, pero esto depende totalmente de ti.

¡Ser creativo!

No creo que la respuesta anterior sea "incorrecta", pero hay grandes áreas de autenticación que no se abordan (o más bien el énfasis está en "cómo implementar sesiones de cookies", no en "qué opciones están disponibles y cuáles son las ventajas comerciales"). -offs".

Mis ediciones/respuestas sugeridas son

  • El problema radica más en la configuración de la cuenta que en la comprobación de la contraseña.
  • El uso de la autenticación de dos factores es mucho más seguro que los métodos más inteligentes de cifrado de contraseñas.
  • No intente implementar su propio formulario de inicio de sesión o almacenamiento de la base de datos de contraseñas, a menos que los datos que se almacenan no tienen valor en la creación de la cuenta y se autogeneran (es decir, estilo Web 2.0 como Facebook, Flickr, etc.)

    1. La autenticación implícita es un enfoque basado en estándares compatible con los principales navegadores y servidores, que no enviará una contraseña ni siquiera a través de un canal seguro.

Esto evita la necesidad de tener "sesiones" o cookies, ya que el propio navegador volverá a cifrar la comunicación cada vez.Es el enfoque de desarrollo más "ligero".

Sin embargo, no lo recomiendo, excepto para servicios públicos de bajo valor.Este es un problema con algunas de las otras respuestas anteriores; no intente volver a implementar los mecanismos de autenticación del lado del servidor; este problema se ha resuelto y es compatible con la mayoría de los principales navegadores.No utilice cookies.No almacene nada en su propia base de datos hecha a mano.Simplemente pregunte, por solicitud, si la solicitud está autenticada.Todo lo demás debe estar respaldado por la configuración y el software confiable de terceros.

Entonces ...

En primer lugar, estamos confundiendo la creación inicial de una cuenta (con una contraseña) con la verificación posterior de la contraseña.Si soy Flickr y creo su sitio por primera vez, el nuevo usuario tiene acceso al valor cero (espacio web en blanco).Realmente no me importa si la persona que crea la cuenta miente sobre su nombre.Si estoy creando una cuenta de la intranet/extranet del hospital, el valor está en todos los registros médicos, por lo que hacer preocuparse por la identidad (*) del creador de la cuenta.

Ésta es la parte muy, muy difícil.El solo Una solución decente es una red de confianza.Por ejemplo, ingresa al hospital como médico.Creas una página web alojada en algún lugar con tu foto, tu número de pasaporte y una clave pública, y los codificas todos con la clave privada.Luego visita el hospital y el administrador del sistema mira su pasaporte, ve si la foto coincide con usted y luego codifica la página web/foto con la clave privada del hospital.A partir de ahora podremos intercambiar claves y tokens de forma segura.Al igual que cualquiera que confíe en el hospital (por cierto, existe la salsa secreta).El administrador del sistema también puede darle una RSA dongle u otra autenticación de dos factores.

Pero esto es un lote una molestia, y poco web 2.0.Sin embargo, es la única forma segura de crear nuevas cuentas que tienen acceso a información valiosa que no es de creación propia.

  1. Kerberos y SPNEGO (mecanismos de inicio de sesión único con un tercero confiable) básicamente el usuario verifica con un tercero confiable.(NB: esto no es de ninguna manera un mensaje en el que no se puede confiar OAuth)

  2. SRP - una especie de autenticación de contraseña inteligente sin un tercero de confianza.Pero aquí nos adentramos en el terreno de que "es más seguro utilizar la autenticación de dos factores, aunque sea más costoso".

  3. SSL lado del cliente: proporcione a los clientes un certificado de clave pública (compatible con todos los navegadores principales, pero plantea dudas sobre la seguridad de la máquina del cliente).

Al final, es una cuestión de equilibrio: cuál es el costo de una violación de la seguridad versus el costo de implementar enfoques más seguros.Algún día podremos ver una adecuada PKI ampliamente aceptado y, por lo tanto, no más formularios de autenticación y bases de datos propios.Un día...

Al realizar hash, no utilice algoritmos hash rápidos como MD5 (existen muchas implementaciones de hardware).Utilice algo como SHA-512.Para las contraseñas, los hashes más lentos son mejores.

Cuanto más rápido puedas crear hashes, más rápido podrá funcionar cualquier verificador de fuerza bruta.Por lo tanto, los hashes más lentos ralentizarán la fuerza bruta.Un algoritmo hash lento hará que la fuerza bruta no sea práctica para contraseñas más largas (más de 8 dígitos)

Un buen artículo sobre una estimación realista de la seguridad de la contraseña es:

Blog técnico de Dropbox » Archivo del blog » zxcvbn:estimación realista de la seguridad de la contraseña

Mi regla favorita con respecto a los sistemas de autenticación:Utilice frases de contraseña, no contraseñas.Fácil de recordar, difícil de descifrar.Más información: Codificación de terror:Contraseñas vs.Frases de pase

Me gustaría agregar una sugerencia que he usado, basada en la defensa en profundidad.No es necesario tener el mismo sistema de autenticación y autenticación para los administradores que los usuarios habituales.Puede tener un formulario de inicio de sesión separado en una URL separada ejecutando código separado para solicitudes que otorgarán altos privilegios.Este puede tomar decisiones que serían una molestia total para los usuarios habituales.Uno de los que he usado es codificar la URL de inicio de sesión para el acceso de administrador y enviarle por correo electrónico la nueva URL al administrador.Detiene cualquier ataque de fuerza bruta de inmediato ya que su nueva URL puede ser arbitrariamente difícil (cadena aleatoria muy larga), pero el único inconveniente de su usuario administrador es seguir un enlace en su correo electrónico.El atacante ya no sabe dónde PUBLICAR.

No sé si sería mejor responder esto como respuesta o como comentario.Opté por la primera opción.

Respecto al punto PARTE IV:Funcionalidad de contraseña olvidada En la primera respuesta, quisiera señalar los ataques sincronizados.

En el Recuerda tu contraseña formularios, un atacante podría potencialmente verificar una lista completa de correos electrónicos y detectar cuáles están registrados en el sistema (consulte el enlace a continuación).

Con respecto al formulario de contraseña olvidada, agregaría que es una buena idea igualar los tiempos entre consultas exitosas y no exitosas con alguna función de demora.

https://crypto.stanford.edu/~dabo/papers/webtiming.pdf

Me gustaría agregar un comentario muy importante:-

  • "En un corporativo, intra- configuración neta", es posible que la mayoría, si no la totalidad, de lo anterior no se aplique.

Muchas corporaciones implementan sitios web de "uso interno únicamente" que son, efectivamente, "aplicaciones corporativas" que han sido implementadas a través de URL.Estas URL pueden (supuestamente...) sólo podrá resolverse dentro de "la red interna de la empresa". (Qué red incluye mágicamente a todos los 'guerreros de la carretera' conectados a VPN).

Cuando un usuario está debidamente conectado a la red antes mencionada, su identidad ("autenticación") es [ya...] "conclusivamente conocido", al igual que su permiso ("autorización") hacer ciertas cosas...como ..."para acceder a este sitio web."

Este servicio de "autenticación + autorización" puede ser proporcionado por varias tecnologías diferentes, como LDAP (Microsoft OpenDirectory), o Kerberos.

Desde tu punto de vista, simplemente sabes esto:eso alguien quién termina legítimamente en su sitio web debe acompañarse por [un medio ambiente variable que contiene mágicamente ...] una "ficha". (es decir. La ausencia de dicha señal debe ser motivo inmediato de 404 Not Found.)

El valor del token no tiene sentido para ti, pero, Si surge la necesidad, "existen medios apropiados" mediante los cuales su sitio web pueda "preguntar [con autoridad] a alguien que sepa (LDAP...etc.)" sobre cualquier y cada(!) pregunta que puedas tener.En otras palabras, lo haces no aprovecharse de cualquier "Lógica local". En cambio, usted pregunta sobre la autoridad e implícitamente confía en su veredicto.

UH Huh ...es bastante un cambio mental de la "Internet salvaje y confusa".

Usar Conexión OpenID o Acceso administrado por el usuario.

Porque nada es más eficiente que no hacerlo en absoluto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top