Pregunta La guía definitiva para la autenticación de sitios web basada en formularios [cerrado]


Autenticación basada en formularios para sitios web

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

Debe incluir temas tales como:

  • Cómo iniciar sesión
  • Cómo desconectarse
  • Cómo permanecer conectado
  • Gestión de cookies (incluida la configuración recomendada)
  • Cifrado SSL / HTTPS
  • Cómo almacenar contraseñas
  • Usando preguntas secretas
  • Olvidé mi nombre de usuario / contraseña
  • Uso de nonces para prevenir solicitudes de falsificaciones entre sitios (CSRF)
  • OpenID
  • Casilla "Recordarme"
  • Autocompletado del navegador de nombres de usuario y contraseñas
  • URL secretas (públicas URL protegido por digest)
  • Comprobando la fortaleza de la contraseña
  • Validación de correo electrónico
  • y mucho más sobre  autenticación basada en formulario...

No debe incluir cosas como:

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

Por favor ayúdenos por:

  1. Sugerir subtemas
  2. Presentando buenos artículos sobre este tema
  3. Editando la respuesta oficial

4992


origen


Respuestas:


PARTE I: Cómo iniciar sesión

Supondremos que ya sabe cómo crear un formulario HTML de inicio de sesión + contraseña que PUBLICA los valores a un script en el lado del servidor para la autenticación. Las siguientes secciones se ocuparán de los patrones de autenticación práctica sólida y de cómo evitar las dificultades de seguridad más comunes.

¿HTTPS o no a HTTPS?

A menos que la conexión ya sea segura (es decir, en túnel mediante HTTPS utilizando SSL / TLS), sus valores de formulario de inicio de sesión se enviarán en texto claro, lo que permite a cualquier persona que escuche en la línea entre el navegador y el servidor web leer los inicios de sesión mediante. Este tipo de intervención telefónica se realiza de manera rutinaria por parte de los gobiernos, pero en general no abordaremos los cables 'de propiedad' excepto para decir esto: si está protegiendo algo importante, use HTTPS.

En esencia, el único práctico La forma de protegerse contra escuchas telefónicas / detección 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-Hellmanbasado en SRP). Cualquier otro método puede ser fácilmente eludido por un atacante que escucha a escondidas.

Por supuesto, si está dispuesto a ser un poco práctico, también puede emplear algún tipo de esquema de autenticación de dos factores (por ejemplo, la aplicación Google Authenticator, un libro de códigos físico de "estilo de 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 autenticación de dos factores, pero no SSL.

(No) Transfiere tu propio cifrado / hash de JavaScript

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

Si bien este es un pensamiento noble, es esencialmente inútil (y puede ser un falla de seguridad) a menos que se combine con uno de los anteriores, es decir, asegurar la línea con una encriptación fuerte o usar un mecanismo de desafío y respuesta comprobado (si no sabes qué es eso, solo debes saber 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 hashing la contraseña puede ser efectivo contra revelación de contraseña, es vulnerable a ataques de repetición, ataques / secuestros 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 pueden comentar el hashing en JavaScript), o ataques de fuerza bruta (ya que le está entregando al atacante tanto el nombre de usuario, como la contraseña saliente y hash).

CAPTCHAS contra la humanidad

CAPTCHAs están destinados a frustrar una categoría específica de ataque: prueba automatizada de diccionario / fuerza bruta sin operador humano. No hay duda de que esta es una amenaza real, sin embargo, hay maneras de lidiar con ella a la perfección que no requieren un CAPTCHA, específicamente esquemas de aceleración de inicio de sesión en el servidor debidamente diseñados - los discutiremos luego.

Sepa que las implementaciones de CAPTCHA no se crean de la misma manera; a menudo no son solucionables por los humanos, la mayoría de ellos son ineficaces contra los robots, todos ellos son ineficaces contra la mano de obra barata del tercer mundo (según OWASP, la tasa actual de explotación es de $ 12 por cada 500 pruebas), y algunas implementaciones pueden ser técnicamente ilegales en algunos países (ver Hoja de trucos de Autenticación OWASP) Si debe usar un CAPTCHA, use Google reCAPTCHA, ya que es resistente a la OCR por definición (ya que utiliza escaneos de libros clasificados por OCR) y se esfuerza por ser fácil de usar.

Personalmente, tiendo a pensar que CAPTCHAS es molesto, y los uso solo como último recurso cuando un usuario no ha podido iniciar sesión varias veces y las demoras de aceleración se ven maximizadas. Esto sucederá en raras ocasiones para ser aceptable, y fortalece el sistema como un todo.

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 altamente publicitados y fugas de datos de usuario que hemos visto en los últimos años, pero debe decirse: No almacene contraseñas en texto claro en su base de datos. Las bases de datos de los usuarios se piratean, filtran o extraen rutinariamente a través de la inyección de SQL, y si está almacenando contraseñas en texto sin formato, eso es un juego instantáneo 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 desde el formulario de inicio de sesión sea correcta? La respuesta es hashing usando un función clave de derivación. Cada vez que se crea un nuevo usuario o se cambia una contraseña, se toma la contraseña y se ejecuta a través de un KDF, como Argon2, bcrypt, scrypt o PBKDF2, convirtiendo la contraseña de texto claro ("correcthorsebatterystaple") en una larga cadena de aspecto aleatorio , que es mucho más seguro 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 transfiere la sal y compara la cadena hash resultante con el valor almacenado en su base de datos. Argon2, brypt y scrypt almacenan la sal con el hash ya. 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 porque el hashing en sí mismo no es suficiente; querrás agregar una llamada 'sal' para proteger el hash contra mesas arcoiris. Una sal evita efectivamente que dos contraseñas que coincidan exactamente se almacenen como el mismo valor hash, evitando que toda la base de datos se analice en una ejecución si un atacante está ejecutando un ataque de adivinación de contraseñas.

No se debe usar un hash criptográfico para el almacenamiento de contraseñas porque las contraseñas seleccionadas por el usuario no son lo suficientemente fuertes (es decir, no contienen suficiente entropía) y un atacante con acceso a los hashes puede completar un ataque de adivinación de contraseñas. Esta es la razón por la cual se usa un KDF, estos de manera efectiva "estirar la llave" lo que significa que cada contraseña que adivine un atacante implica la iteración del algoritmo de hash varias veces, por ejemplo, 10.000 veces, haciendo que la contraseña del atacante adivine 10.000 veces más despacio.

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

Una vez que el servidor ha verificado el inicio de sesión y la contraseña en su base de datos de usuarios y ha encontrado una coincidencia, el sistema necesita una forma de recordar que el navegador se ha autenticado. Este hecho solo 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 cómo funciona: una 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á usando un marco MVC, esto ya se maneja sin dudas.

Si es posible, asegúrese de que la cookie de sesión tenga los indicadores seguros y de solo HTTP establecidos cuando se envíen al navegador. El indicador httponly proporciona cierta protección contra la cookie que se lee con un ataque XSS. El indicador de seguridad garantiza que la cookie solo se envíe de vuelta a través de HTTPS y, por lo tanto, protege contra los ataques de detección de red. El valor de la cookie no debe ser predecible. Cuando se presente 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 (funcionalidad "recordarme") son una zona de peligro; por un lado, son completamente tan seguros como los inicios de sesión convencionales cuando los usuarios entienden cómo manejarlos; y, por otro lado, representan un enorme riesgo de seguridad en manos de usuarios descuidados, que pueden utilizarlos en computadoras públicas y olvidarse de cerrar la 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 para los sitios web que visito con regularidad, pero sé cómo manejarlos de manera segura. Si está seguro de que sus usuarios saben lo mismo, puede usar los inicios de sesión persistentes con la conciencia limpia. De lo contrario, puede suscribirse a la filosofía de que los usuarios descuidados con sus credenciales de inicio de sesión se encargarán de ellos si son pirateados. No es como si fuéramos a las casas de nuestros usuarios y arrancáramos todas esas notas Post-it que inducen palmas con contraseñas que han alineado en el borde de sus monitores, tampoco.

Por supuesto, algunos sistemas no pueden darse el lujo de tener alguna cuentas pirateadas; para tales sistemas, no hay forma de que pueda justificar 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 Paragon Initiative sobre el tema. Tendrá que obtener un montón de elementos correctos, y el artículo hace un excelente trabajo al explicar cada uno.

  2. Y solo para reiterar uno de los escollos más comunes, NO ALMACENE LA COOKIE PERSONALIZADA DE INICIO DE SESIÓN (TOKEN) EN SU BASE DE DATOS, ¡SOLO UN RESTO DE ESTO! El token de inicio de sesión es Equivalente de contraseña, por lo que si un atacante tiene en sus manos su base de datos, podrían usar los tokens para iniciar sesión en cualquier cuenta, como si fueran combinaciones de inicio de sesión y contraseña de texto claro. Por lo tanto, use hash (según https://security.stackexchange.com/a/63438/5002 un hash débil funcionará muy bien para este propósito) cuando se almacenan tokens de inicio de sesión persistentes.

PARTE III: Uso de preguntas secretas

No implemente 'preguntas secretas'. La función de 'preguntas secretas' es un anti patrón de seguridad. Lea el documento del enlace número 4 de la lista DEBE LEER. Puede preguntarle a Sarah Palin sobre eso, después de su Yahoo! la cuenta de correo electrónico fue pirateada durante una campaña presidencial anterior porque la respuesta a su pregunta de seguridad fue ... "Wasilla High School"!

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

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

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

  • Cualquier pregunta que sea más fácil de responder que adivinar su contraseña. Cuál, para cualquier contraseña decente, es cada pregunta que puedes imaginar

En conclusión, las preguntas de seguridad son intrínsecamente 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 cual las preguntas de seguridad aún existen en la naturaleza es que convenientemente ahorran el costo de unas pocas 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 use preguntas de seguridadpara manejar contraseñas de usuario olvidadas / perdidas; tampoco es necesario decir que nunca debe enviar por correo electrónico a los usuarios sus contraseñas reales. Existen al menos dos peligros más comunes para evitar en este campo:

  1. No lo hagas Reiniciar una contraseña olvidada para una contraseña segura autogenerada: tales contraseñas son notoriamente difíciles de recordar, lo que significa que el usuario debe cambiarlas o escribirlas, por ejemplo, en un color amarillo brillante Post-It en el borde de su monitor. En lugar de establecer una nueva contraseña, simplemente deje 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 anotarlo).

  2. Siempre hash el 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 ser hash en caso de que un atacante tenga en sus manos su base de datos. Cuando se solicita un código de contraseña perdida, envíe el código de texto claro a la dirección de correo electrónico del usuario, luego cópielo, guarde el hash en su base de datos y tirar el original. Al igual que una contraseña o un token de inicio de sesión persistente.

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

PARTE V: Comprobación de la fortaleza de la contraseña

Primero, querrá leer este pequeño artículo para una verificación de la realidad: Las 500 contraseñas más comunes

De acuerdo, entonces tal vez la lista no es la canónico lista de contraseñas más comunes en alguna sistema en cualquier lugar, pero es una buena indicación de lo mal que la gente elegirá sus contraseñas cuando no haya una política implementada. Además, la lista se ve espantosamente cerca de su hogar cuando la compara con análisis públicamente disponibles de contraseñas recientemente robadas.

Entonces: sin requisitos mínimos de seguridad de contraseñas, el 2% de los usuarios usa una de las 20 contraseñas más comunes. Significado: si un atacante obtiene solo 20 intentos, 1 de cada 50 cuentas en su sitio web serán crackables.

Frustrar esto requiere 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 análisis de diseño de diccionario y 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 fuerza de la contraseña y mostrando un medidor de fuerza visual para un usuario es bueno, pero insuficiente. A menos que se haga cumplir, muchos usuarios lo ignorarán.

Y para una versión refrescante de la facilidad de uso de las contraseñas de alta entropía, Randall Munroe Fortaleza de la contraseña xkcd es muy recomendable

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

Primero, mira los números: Velocidades de recuperación de contraseña: ¿por cuánto tiempo se pondrá de pie su contraseña?

Si no tiene tiempo para revisar las tablas en ese enlace, esta es la lista de ellas:

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

  2. Se necesita prácticamente sin tiempo para descifrar una contraseña alfanumérica de 9 caracteres, si es case insensible

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

  4. Sin embargo, tomaría una cantidad de tiempo desmesurada para 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, muchísimo, pero podemos centrarnos en la parte más importante: el hecho de evitar un gran número de intentos de inicio de sesión sucesivos de disparos rápidos (es decir, el fuerza bruta ataque) realmente no es tan difícil. Pero prevenirlo derecho no es tan fácil como parece.

En términos generales, tiene tres opciones que son todas efectivas contra los ataques de fuerza bruta (y ataques de diccionario, pero dado que ya está empleando una sólida política de contraseñas, no deberían ser un problema):

  • Presente un CAPTCHA después de N intentos fallidos (molesto como el infierno y a menudo ineficaz, pero me estoy repitiendo aquí)

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

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

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 = 2 segundos de retraso
  • 3 intentos fallidos = retraso de 4 segundos
  • 4 intentos fallidos = 8 segundos de retraso
  • 5 intentos fallidos = 16 segundos de retraso
  • etc.

DoS atacar 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 como un tiempo de espera o período refractario durante el cual los intentos de inicio de sesión a 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 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 = 15-30 minutos de retraso

DoS atacar este esquema sería bastante poco práctico, pero ciertamente factible. Además, podría ser relevante tener en cuenta que un retraso tan largo puede ser muy molesto para un usuario legítimo. A los usuarios olvidados no les gustará.

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

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

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

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

Este esquema final fue tomado de las sugerencias de mejores prácticas de OWASP (enlace 1 de la lista DEBE LEER), y se debe considerar la mejor práctica, incluso si se admite que está en el lado restrictivo.

Sin embargo, como regla general, diría que, 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 fuertes (números alfanuméricos sensibles a las mayúsculas y minúsculas + símbolos) de más de 9 caracteres, podría darles a los usuarios 2-4 intentos de contraseña no retardada antes de activar la aceleración.

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

Además, tiene sentido hacer una aceleración más agresiva en las cuentas de administrador, ya que esos son los puntos de entrada más atractivos.

PARTE VII: Ataques de fuerza bruta distribuidos

Solo como un lado, los atacantes más avanzados intentarán eludir el límite de inicio de sesión "difundiendo sus actividades":

  • Distribuir los intentos en una botnet para evitar marcar la dirección IP

  • En lugar de elegir un usuario y probar las 50,000 contraseñas más comunes (que no pueden, debido a nuestra aceleración), escogerán LA contraseña más común y la probarán contra 50,000 usuarios en su lugar. De esta forma, no solo logran evitar las medidas de máximo intento como los CAPTCHA y la aceleración de inicio de sesión, 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 el número 49.995.

  • Espaciar las solicitudes de inicio de sesión para cada cuenta de usuario, por ejemplo, con 30 segundos de diferencia, para escabullirse por debajo del radar

Aquí, la mejor práctica sería registrar el número de inicios de sesión fallidos, todo el sistemay utilizar un promedio continuo de la frecuencia de inicio de sesión incorrecto de su sitio como base para un límite superior que luego impone a todos los usuarios.

Demasiado abstracto? Déjame reformular:

Supongamos que su sitio ha tenido un promedio de 120 inicios de sesión incorrectos por día en los últimos 3 meses. Usando eso (promedio de ejecución), su sistema puede establecer el límite global en 3 veces eso, es decir. 360 intentos fallidos durante 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 incluso mejor, supervisa la velocidad de aceleración y dispara en un umbral calculado), activa la limitación de inicio de sesión en todo el sistema, lo que significa pequeños retrasos para TODOS los usuarios (aún, a excepción de los inicios de sesión de 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 los tramposos difíciles en defenderse de los 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 que se anoten o pierdan, por el robo de las computadoras portátiles o por el ingreso de usuarios a los sitios de phishing. Los inicios de sesión pueden protegerse aún más con autenticación de dos factores, que utilizan 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 por completo a un servicio de inicio de sesión único, donde otro proveedor maneja la recolección de credenciales. Esto lleva el problema a un tercero confiable. Google y Twitter ofrecen servicios SSO basados ​​en estándares, mientras que Facebook ofrece una solución propietaria similar.

DEBE LEER ENLACES Acerca de la autenticación web

  1. Guía de OWASP para la autenticación / Hoja de trucos de Autenticación OWASP
  2. Lo que se debe y no se debe hacer con la autenticación de clientes en la web (documento de investigación muy legible del MIT)
  3. Wikipedia: cookie HTTP
  4. Preguntas de conocimiento personal para la autenticación alternativa: preguntas de seguridad en la era de Facebook (documento de investigación de Berkeley muy legible)

3497



Artículo definitivo

Enviando credenciales

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

  • Si la conexión entre el cliente y el servidor no está encriptada, todo lo que haces es vulnerable a los ataques de hombre en el medio. 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 del cliente y hacerse pasar por los usuarios a la perfección, etc. etc. SSL con Autoridades de certificación de confianza está diseñado para prevenir ataques MitM.
  • La contraseña hash recibida por el servidor es menos seguro si no realiza trabajo redundante adicional en el servidor.

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

Almacenamiento de contraseñas

Nunca almacene contraseñas como texto sin formato en la base de datos. Ni siquiera si no le importa la seguridad de su propio sitio. Asuma 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 el original. Y asegúrese de que la contraseña no aparezca en los registros de acceso o de la aplicación. OWASP recomienda el uso de Argon2 como su primera opción para nuevas aplicaciones. Si no está disponible, se debe usar PBKDF2 o scrypt en su lugar. Y finalmente, si ninguno de los anteriores está disponible, use bcrypt.

Los hash por sí mismos también son inseguros. Por ejemplo, las contraseñas idénticas significan hashes idénticos: esto hace que las tablas de búsqueda de hash sean una forma efectiva de descifrar muchas contraseñas al mismo tiempo. En cambio, almacene el salado picadillo. Una sal es una cadena adjunta a la contraseña antes de la mezcla: use una sal diferente (aleatoria) por usuario. La sal es un valor público, por lo que puede almacenarlos con el hash en la base de datos. Ver aquí para más sobre esto.

Esto significa que no puede enviar al usuario sus contraseñas olvidadas (porque solo tiene el hash). No restablezca la contraseña del usuario a menos que haya autenticado al usuario (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 es mejor. Leer PARTE III: Uso de 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 envía al usuario una cookie de sesión. El servidor puede recuperar el nombre de usuario o ID de la cookie, pero nadie más puede generar dicha cookie (TODO explicar los mecanismos).

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

Si desea autenticar a sus usuarios, puede establecer una cookie persistente, pero debe ser distinta de una cookie de sesión completa. Puede establecer un indicador adicional que el usuario ha iniciado sesión automáticamente y necesita iniciar sesión para operaciones confidenciales reales. Esto es popular entre los sitios de compras que desean ofrecerle una experiencia de compra personalizada y sin problemas, pero aún así proteger sus detalles financieros. Por ejemplo, cuando regresa a visitar Amazon, le muestran una página que parece haber iniciado sesión, pero cuando va a realizar un pedido (o cambia su dirección de envío, tarjeta de crédito, etc.), le piden que confirme tu contraseña.

Los sitios web financieros, como bancos y tarjetas de crédito, por otro lado, solo tienen datos confidenciales y no deben permitir el inicio de sesión automático o un modo de baja seguridad.

Lista de recursos externos


387



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!

Voy a seguir adelante y mencionar la propuesta de Mozilla ID de navegador (o quizás más precisamente, el Protocolo de correo electrónico verificado) en el espíritu de encontrar una ruta de actualización para mejores 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 encontrar buenas soluciones a este problema.
  2. La realidad actual es que la mayoría de los sitios web usan 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 sensible 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 confiables implícitamente (la idea de un agente de usuario es actuar en nombre del usuario), pueden ayudar a mejorar esta situación.
  5. La principal fuerza que frena el progreso aquí es punto muerto de implementación. Las soluciones deben descomponerse en pasos que brinden algún beneficio incremental por sí mismos.
  6. El método descentralizado más simple para expresar identidad que está integrado en la infraestructura de Internet es el nombre de dominio.
  7. Como segundo nivel de expresión de identidad, cada dominio maneja su propio conjunto de cuentas.
  8. La forma "cuenta"@dominio "es conciso y está respaldado por una amplia gama de protocolos y esquemas de URI. Tal identificador es, por supuesto, más universalmente reconocido como una dirección de correo electrónico.
  9. Los proveedores de correo electrónico ya son los principales proveedores de identidad de facto en línea. Los flujos de restablecimiento de contraseña actuales generalmente le permiten tomar el control de una cuenta si puede probar que controla la dirección de correo electrónico asociada de esa cuenta.
  10. El protocolo de correo electrónico verificado fue propuesto para proporcionar un método seguro, basado en criptografía de clave pública, para simplificar el proceso de probar al dominio B que tiene una cuenta en el dominio A.
  11. Para los navegadores que no son compatibles con el Protocolo de correo electrónico verificado (actualmente todos ellos), Mozilla proporciona un complemento que implementa el protocolo en el código JavaScript del lado del cliente.
  12. Para los servicios de correo electrónico que no son compatibles con el Protocolo de correo electrónico verificado, el protocolo permite a terceros actuar como un intermediario de confianza, afirmando que han verificado la propiedad de una cuenta por parte de un usuario. No es deseable tener un gran número de dichos terceros; esta capacidad solo está pensada para permitir una ruta de actualización, y es 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 confiable. Los proveedores de servicios (es decir, las partes que confían) que implementan el protocolo de correo electrónico verificado pueden optar por confiar en las afirmaciones de Mozilla o no. El servicio de Mozilla verifica la propiedad de la cuenta de los usuarios utilizando los medios convencionales para enviar un correo electrónico con un enlace de confirmación.
  14. Los proveedores de servicios pueden, por supuesto, ofrecer este protocolo como una opción además de cualquier otro método (s) de autenticación que deseen ofrecer.
  15. Una gran ventaja de la interfaz de usuario que se busca aquí es el "selector de identidad". Cuando un usuario visita un sitio y decide autenticarse, su navegador le muestra una selección de direcciones de correo electrónico ("personal", "trabajo", "activismo político", etc.) que pueden usar para identificarse en el sitio.
  16. Otra gran ventaja de la interfaz de usuario que se busca como parte de este esfuerzo es ayudando al navegador a saber más sobre la sesión del usuario - con quién están registrados actualmente, principalmente - por lo que puede mostrar eso en el navegador Chrome.
  17. Debido a la naturaleza distribuida de este sistema, evita el bloqueo de sitios importantes como Facebook, Twitter, Google, etc. Cualquier persona puede ser propietaria de su propio dominio y, por lo tanto, actuar como su propio proveedor de identidad.

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


146



Solo pensé en compartir esta solución que encontré que estaba funcionando bien.

Yo lo llamo el Campo simulado (Aunque no he inventado esto, no me acrediten).

En resumen: solo tiene que insertar esto en su <form> y verifique que esté vacío al momento de validar:

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

El truco es engañar a un bot para que piense que tiene que insertar datos en un campo requerido, 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 como "compañía", "teléfono" o "dirección de correo electrónico". Solo elija algo que sepa que no necesita y lo que suena como 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 más te convenga - solo no lo hagas establecer la entrada type a hidden o de lo contrario el bot no se enamorará.

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

Ejemplo:

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

En caso de un bot: El bot verá un campo cuyo tipo es text y un nombre email (o como sea que lo haya llamado) y lógicamente intentará llenarlo con datos apropiados. No le importa si diseñó el formulario de entrada con un poco de 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 más grande que 0 caracteres.

Utilicé este método en un libro de visitas en combinación con CAPTCHA, y no he visto una sola publicación de spam desde entonces. Antes había utilizado una solución solo de CAPTCHA, pero finalmente resultó en aproximadamente cinco mensajes de spam cada hora. Agregar el campo ficticio en el formulario ha detenido (al menos hasta ahora) la aparición de todo el correo no deseado.

Creo que esto también se puede usar muy 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 ella. También debe pensar en las personas que usan algún tipo de autocompletado (como la mayoría de los navegadores han incorporado) para autocompletar todos los campos del formulario. También podrían recoger un campo ficticio.

También puede variar esto un poco al dejar el campo ficticio visible pero fuera de los límites de la pantalla, pero esto depende totalmente de usted.

¡Ser creativo!


120



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

Mis ediciones / respuestas sugeridas son

  • El problema radica más en la configuración de la cuenta que en la verificación de contraseñas.
  • El uso de autentificación de dos factores es mucho más seguro que los medios más inteligentes de encriptación de contraseñas
  • NO intente implementar su propio formulario de inicio de sesión o almacenamiento de contraseñas en la base de datos, a menos que los datos almacenados no tienen ningún valor en la creación de la cuenta y son autogenerados (es decir, estilo web 2.0 como Facebook, Flickr, etc.)

    1. La Autenticación Digest es un enfoque basado en estándares compatible con todos los principales navegadores y servidores, que no enviará una contraseña incluso a través de un canal seguro.

Esto evita la necesidad de tener "sesiones" o cookies, ya que el navegador en sí mismo volverá a encriptar la comunicación. 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 reimplementar 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 use cookies No almacene nada en su propia base de datos enrollada a mano. Simplemente pregunte, por solicitud, si la solicitud está autorizada. Todo lo demás debe ser compatible con la configuración y el software de confianza de terceros.

Asi que ...

Primero, estamos confundiendo la creación inicial de una cuenta (con una contraseña) con el volver a verificar la contraseña posteriormente. Si soy Flickr y creo su sitio por primera vez, el nuevo usuario tiene acceso a 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 se encuentra en todos los registros médicos, y entonces hacer preocuparse por la identidad (*) del creador de la cuenta.

Esta es la parte muy difícil. los solamente una solución decente es una red de confianza. Por ejemplo, te unes al hospital como un doctor. Usted crea una página web alojada en algún lugar con su foto, su número de pasaporte y una clave pública, y los pica 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 ajusta el hash de la página web / foto con la clave privada del hospital. A partir de ahora podemos intercambiar claves y tokens de forma segura. Al igual que cualquier persona que confía en el hospital (por cierto, la salsa secreta). El administrador del sistema también puede darle un RSA dongle u otra autenticación de dos factores.

Pero esto es un mucho de molestias, y no muy web 2.0. Sin embargo, es la única forma segura de crear cuentas nuevas que tienen acceso a información valiosa que no se crea por sí misma.

  1. Kerberos y SPNEGO - mecanismos de inicio de sesión único con un tercero de confianza - básicamente el usuario verifica contra un tercero de confianza. (Nota: esto no es de ninguna manera no ser confiable OAuth)

  2. SRP - tipo de autenticación de contraseña inteligente sin un tercero de confianza. Pero aquí estamos entrando en el reino de "es más seguro usar autenticación de dos factores, incluso si eso es más costoso"

  3. SSL lado del cliente: otorgue a los clientes un certificado de clave pública (soporte en todos los principales navegadores), pero genera dudas sobre la seguridad de la máquina cliente.

Al final, se trata de una compensación: ¿cuál es el costo de una violación de seguridad frente al costo de implementar enfoques más seguros? Un día, podemos ver un buen PKI ampliamente aceptado y por lo tanto no hay más formularios de autenticación y bases de datos enrollados propios. Un día...


71



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

Cuanto más rápido pueda crear hashes, más rápido podrá funcionar cualquier verificador de fuerza bruta. Los hash más lentos ralentizarán el forzamiento bruto. Un algoritmo hash lento hará que el forzamiento bruto sea poco práctico para contraseñas más largas (8 dígitos +)


48



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

Blog de Dropbox Tech »Archivo del blog» zxcvbn: estimación realista de la intensidad de la contraseña


46



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


41



Me gustaría agregar una sugerencia que he usado, basada en la defensa en profundidad. No necesita tener el mismo sistema de autenticación y autenticación para administradores como usuarios regulares. Puede tener un formulario de inicio de sesión separado en una URL separada ejecutando un código separado para las solicitudes que otorgarán privilegios altos. Este puede tomar decisiones que serían un dolor total para los usuarios regulares. Uno de esos que he usado es codificar la URL de inicio de sesión para el acceso de administrador y enviar por correo electrónico al administrador la nueva URL. 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 para el usuario administrador es seguir un enlace en su correo electrónico. El atacante ya no sabe dónde enviar POST.


20



No sé si es mejor responder esto como una respuesta o un comentario. Opté por la primera opción.

En cuanto a poing PARTE IV: Funcionalidad de contraseña olvidada en la primera respuesta, quisiera hacer un punto acerca de Timing Attacks.

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

En cuanto 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 retraso.

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


12