php - Iniciar sesión sin HTTPS, ¿cómo proteger?
ajax security (20)
Iniciar sesión sin HTTPS, ¿cómo proteger?
Como no hay un canal seguro entre su servidor y su cliente:
- porque no hay un canal seguro, cualquiera puede fisgonear su tráfico.
- porque cualquiera puede husmear el tráfico, estás abierto a un ataque MITM.
- porque está abierto al ataque MITM, no hay garantía de que el cliente vea una página legítima.
- porque las páginas no son legítimas y su página no está siendo servida (el hombre del medio está atendiendo las páginas), todos los trucos utilizados en el servidor se vuelven inútiles.
¿Qué puedes hacer? Teóricamente?
- tanto el cliente como el servidor necesitan usar el cifrado para hacer que el snooping / MITM sea menos susceptible.
- asumir que no puedes tener un apretón de manos,
- supongamos que su cliente ya tiene su clave y sabe cómo hablar el mismo galimatías que su servidor.
- ¿Qué tal un poco de SSL sobre HTTP pero envuelto en un mensaje codificado en base64 para algunos galimatías?
Pero espera ... Como dijiste que no había ningún binario mágico, ni un plugin, ni siquiera RSA, no sé si esto es posible excepto para el cifrado interno (algo potencialmente débil).
-
Para una aplicación web, cuando HTTPS no está disponible como medida de seguridad, ¿es posible hacer que el inicio de sesión sea seguro? P.ej:
- Tokenize inicios de sesión, para hacer que los ataques repetidos sean difíciles?
- De alguna manera, cifrar la contraseña enviada desde un campo de contraseña HTML?
En particular, estoy usando CakePHP y una llamada AJAX POST para activar la autenticación (incluye el nombre de usuario y la contraseña).
Actualización sobre el problema:
- HTTPS no está disponible. Período. Si no te gusta la situación, considérala una pregunta teórica.
- No hay requisitos explícitos, tienes lo que HTTP, PHP y un navegador (cookies, JavaScript, etc.) ofrecen en la vida real (sin binarios mágicos de RSA, complementos de PGP).
- La pregunta es, ¿qué es lo mejor que se puede sacar de esta situación ?, eso es mejor que enviar las contraseñas de texto plano. Conocer los inconvenientes de cada una de esas soluciones es una ventaja.
- Cualquier mejora mejor que las contraseñas simples es bienvenida. No buscamos una solución 100% l33tG0Dhx0r-proff. Difícil de descifrar es mejor que piratear, que es mejor que un simple olfateo que revela la contraseña.
¿Qué pasa con la Autenticación HTTP Digest ? Proporciona seguridad mediante hash MD5, nombre de usuario y contraseña (entre otras cosas) antes de enviarlo al servidor. MD5 no es realmente seguro, pero es una buena forma de seguridad simple con HTTP.
Por supuesto, esto no evita que los piratas informáticos cambien el mensaje ... pero protege su contraseña.
Antes de intentar responder, me gustaría mencionar que cualquier otra respuesta aquí es correcta sobre HTTPS / STS. HTTPS es una batalla endurecida, de confianza y, probablemente, tu mejor opción, estoy seguro de que estás cansado de escucharla. Ahora, no soy un experto en seguridad, pero este es uno de los problemas que he pensado y creo crear un camino. Nunca lo he usado, y les pido a todos que hagan agujeros tanto como sea posible. Solo protege contra un ataque de hombre en el medio.
La idea es lograr la parte secreta compartida sin el apretón de manos, incluso si eso significa llevar a cuestas otro servicio que es seguro (como un correo electrónico, suponiendo que usan algo con TLS para leerlo).
Parte 1: la configuración
Seleccione un cifrado simétrico, quizás Rijndael.
Seleccione un algoritmo hash, SHA256 / 512 son mis favoritos.
Cree una sal grande, algún dato aleatorio, idealmente algo carnoso. 512 bytes tal vez. Vamos a llamarlo GSALT. (piense en ello como una variable llamada GSALT). Esta será una sal global. Probablemente un buen material de archivo de configuración.
En su base de datos, los datos del usuario deben contener un campo de nombre de usuario, un campo userhash, un campo de contraseña, un campo saliente, un campo clave y un campo keyhash (además de lo que desee, solo estoy cubriendo campos relevantes). Explicaré lo que debe contener cada campo:
- nombre de usuario: el nombre de usuario real que la persona eligió durante el registro.
- salt: una cadena generada aleatoriamente, debe tener al menos 32 caracteres de longitud. Me gusta convertirlos en 64. Eso podría ser un desperdicio, pero estoy paranoico. Llamemos a esto LSALT.
- contraseña: el hash de GSALT + contraseña real + LSALT. Anexado en ese orden.
- userhash: debe contener el hash del nombre de usuario GSALT +. Indicado para la velocidad.
- clave: debe contener una cadena aleatoria (es básicamente otra sal, pero una que usaremos de forma semipública)
- keyhash: contiene el hash de GSALT + contraseña + clave real. Anexado en ese orden.
Parte 2: Registrarse un nuevo usuario
- En su formulario de suscripción, solicite un nombre de usuario, correo electrónico, pero no contraseña.
- Una vez validado y aceptado, genere una contraseña del lado del servidor y envíela a su correo electrónico.
- En su base de datos, genere los diferentes valores mencionados en el paso uno (userhash, password, salt, key, keyhash, etc.)
Parte 3: Autenticación
- Incluye la sal global con el inicio de sesión.
- En un intento de inicio de sesión:
- Crear userhash mediante hash GSALT + nombre de usuario
- Crear un passhash mediante hash GSALT + contraseña
- Enviar userhash y passhash al servidor
- En el servidor que los recibe:
- Encuentra el registro de usuario que coincide con userhash
- Obtenga la contraseña y el valor de sal de ese registro, y verifique que este nombre de usuario tenga la contraseña correcta mediante hash passhash + user salt (LSALT).
- Si es una coincidencia, su usuario está autenticado. Produce un nonce (un número aleatorio o cadena de un tamaño decente tal que no se puede adivinar)
- Encripta el nonce usando el valor keyhash como la clave de cifrado, y produce un token con el nonce en su carga útil. Este token debe usar una tecla separada del lado del servidor (ver esquema JWT).
- Envíe la clave, el código cifrado y el token.
- El cliente recibe la clave, el código cifrado y el token.
- El cliente hashes GSALT + contraseña real + clave para producir la clave de cifrado necesaria para descifrar el nonce.
- Deseche todos los demás valores, excepto el nonce y el token en el lado del cliente.
- Con cada solicitud del lado del cliente, encripte los contenidos usando el nonce como clave. Envíe los contenidos encriptados con el token. No cifre el token. Simplemente envíe el token como un valor separado de los datos de solicitud.
- El servidor recibe la solicitud cifrada y el token, descifra el token y luego usa el nonce para descifrar los contenidos de la solicitud.
- El servidor genera una respuesta, la encripta usando el nonce, la envía hacia abajo ... hacia adelante y hacia atrás / etc.
Cuestiones
- Es computacionalmente caro, en ambos lados.
- No protege contra muchos otros ataques, y es probable que esté más abierto a un ataque de canal lateral.
- Esa sal global es básicamente un negocio para siempre: /
- No soy un experto en seguridad, esto podría no ser hermético. "No enrolles sus propios esquemas de cifrado" se repite como un loro por una buena razón.
- Un pirata informático lo suficientemente dedicado podría construir una tabla de arco iris o comprobar la fuerza bruta de su contraseña hash.
- Es una trampa porque usamos el correo electrónico para eludir un área problemática.
Aún así, ¡es un experimento de pensamiento divertido! Espero que ayude a alguien (especialmente si eso significa que los empuja a usar HTTPS)
Como no puede hacer SSL en el servidor web, y no es un experto en seguridad, busque un servicio de autenticación seguro existente que pueda utilizar, y permita que manejen tanto el SSL como las complejidades de manejar las credenciales por usted.
En particular, le sugiero que utilice un servicio gratuito de autenticación de terceros, como OpenID . Tienen bibliotecas para PHP incluida una para CakePHP .
Editar: (sobre riesgos)
Si bien utilizar un servicio de autenticación segura de terceros (que usa HTTPS en sí mismo) puede mitigar el problema al realizar la autenticación sin usar HTTPS (en su servidor), no elimina completamente la posibilidad de ataques.
Los dos ataques más comunes serían los ataques de repetición y el secuestro de sesión donde el atacante puede volver a utilizar un token de sesión de inicio de sesión genuino más tarde o usar un token de sesión válido para su propio propósito malicioso.
El ataque de repetición puede mitigarse con la expiración del token de sesión, y preferiblemente mediante el uso de un nonce para evitar la repetición de sesión y para reducir el riesgo de secuestro de sesión. Con un nonce, una sesión legítima genera un error si se piratea con éxito, porque el nonce ha expirado (se ha utilizado), por lo que su propia sesión ya no es válida.
Si no puede usar HTTPS para cifrar el token de la sesión mientras se transmite desde y hacia su servidor, no puede evitar por completo los ataques activos, como el secuestro de sesión o el ataque man-in-the-middle . Esto puede ser aceptable en algunos casos, como sitios web con una base de usuarios pequeña para uso no comercial.
Como sugirió, puede generar un token único cada vez que se crea la página. Ese mismo token debería enviarse de vuelta con los datos del formulario y no podría reutilizarse. También puede mantener la contraseña segura mediante el uso de JavaScript para hash it, si puede confiar en que los usuarios lo habiliten.
Sin embargo, este esquema aún no es seguro. Un atacante aún podría ver todo lo que pasa por el cable. Podrían interceptar el token y enviarle una respuesta antes que el usuario. O simplemente podrían esperar a que alguien inicie sesión, robar las credenciales de esa persona (a medida que se envían por el cable) y simplemente hacer su propia solicitud de inicio de sesión más adelante.
Conclusión : debe usar HTTPS para garantizar que el sitio sea seguro.
Eche un vistazo a "El protocolo de contraseña remota segura" .
En lugar de formularlo yo mismo, permítanme citar de su sitio web:
El protocolo Secure Remote Password realiza una autenticación remota segura de contraseñas cortas de datos humanos y resiste los ataques pasivos y activos de la red.
y:
[El] protocolo combina técnicas de pruebas de conocimiento cero con protocolos asimétricos de intercambio de claves y ofrece un rendimiento significativamente mejorado en comparación con métodos extendidos fuertes que resisten ataques de verificador robado como EKE aumentado o B-SPEKE.
Aunque la Universidad de Stanford no proporciona implementaciones para PHP y JavaScript, se vinculan con algunas implementaciones de terceros.
Uno de esos enlaces lleva a "Clipperz" , que es un administrador de contraseñas en línea. También está disponible como una edición de comunidad en GitHub. Allí alojan su "javascript-crypto-library" , que implementa el protocolo y el "password-manager" , que contiene backends escritos en PHP y Python.
No puedo decir lo difícil que sería extraer las partes relevantes del código, pero tal vez puedas reutilizar su implementación (está licenciado bajo AGPL).
Editar 2014/10/24:
El artículo de Wikipedia sobre SRP enumera algunas implementaciones más. Relevante para PHP / JS:
Es difícil asegurar la comunicación sin un trusted third party
, sin embargo, hay algunos trucos de seguridad para usted:
NO exponga la información sensible de los usuarios a la red pública.
Toda información sensible debe estar bien cifrada o en clave pública. Preste atención: si elige cifrar la información confidencial de los usuarios mediante una clave pública, asegúrese de que el usuario pueda verificar la clave pública. Por ejemplo, puede enviar algún tipo de huella digital de clave pública al usuario a través de SMS o incluso una llamada automática.
Generar un SECRETO COMPARTIDO después de iniciar sesión con éxito
Después de una transacción de inicio de sesión segura, se debe generar un secreto compartido. El procedimiento de generación podría referirse a SSL Handshake
. Preste atención: una vez que se genera el secreto compartido, debe ser transportado nunca más. La única función de esto es cifrar / descifrar los datos entre Server
y Broswer
DEBE haber una verificación en dos pasos para evitar ataques repetidos
Que estos trucos te ayuden
HTTPS es absolutamente vital para mantener una conexión segura entre un sitio web y un navegador. Las redes wifi públicas ponen a los usuarios en riesgo y, cuando se usan correctamente, HTTPS es la única herramienta que puede proteger las cuentas de usuario de esta vulnerabilidad .
Si su host no es compatible con HTTPS, se puede usar un servicio como Cloudflare Universal SSL para garantizar que todos los navegadores se conecten a su sitio mediante HTTPS, incluso si su servidor no es compatible con SSL / TLS . La conexión entre Cloudflare y su sitio web seguirá estando desprotegida, pero este servicio Cloudflare está destinado a proteger a los usuarios contra las amenazas que se encuentran en las redes wifi públicas. Desde la perspectiva de un analizador de penetración, no proporcionar HTTPS es altamente sospechoso, si no está proporcionando un requisito de seguridad básico como la entrega de tráfico, entonces, ¿qué otros requisitos de seguridad le falta? Los certificados HTTPS se pueden obtener de forma gratuita con Let''s Encrypt o Start SSL , no existe un motivo legítimo para no admitir HTTPS.
HTTPS es vital porque hace mucho más que simplemente "encriptar contraseñas". Otra función importante es evitar que el usuario inicie sesión en un servidor malicioso que se hace pasar por un servidor real. El uso de un sistema para proteger solo la contraseña sigue siendo una violación de OWASP A9 - Protección insuficiente de la capa de transporte porque aún estaría transmitiendo credenciales de sesión en texto plano, que es todo lo que el atacante necesita ( Firesheep ).
La criptografía basada en JavaScript no se puede usar para construir una capa de transporte segura .
"Ingreso de Tokenize": si un atacante está olfateando el tráfico, tendrá el nombre de usuario / contraseña de texto plano y luego puede iniciar sesión con estas nuevas credenciales. (Reproducción de ataque)
"Encriptar de algún modo la contraseña transmitida": una vez que la persona ha iniciado sesión, un atacante puede oler el tráfico para obtener la identificación de la sesión válida (cookie) y luego usar esto en vez de iniciar sesión. Si toda la sesión estaba protegida con SSL / TLS, Esto no es un problema.
Existen otros ataques más complejos que afectan tanto a este sistema como a nuestra infraestructura SSL actual. El ataque SSLStrip entra en mayor detalle. Recomiendo encarecidamente ver la charla Blackhat 2009 de Moxie Marlinspike , que conduce al estándar HTTP-Strict-Transport-Security .
HTTPS tiene numerosos casos de uso, la mayoría de los cuales están diseñados para defenderse contra los ataques Man-in-the-middle. Cualquiera con la mentalidad de un pirata informático se estremecerá al decirte que no hay otro camino que no sea la forma establecida de lograr algo. El hecho es que solo porque use TLS (el estándar que usa HTTPS moderno), no significa que lo esté usando bien. Además, el solo uso de TLS no evita que alguien explote las debilidades conocidas. Del mismo modo que puede encontrar maneras creativas de proteger sus datos, hay personas que están encontrando maneras creativas de explotar sus medidas de seguridad.
¿Entonces lo que hay que hacer?
En primer lugar, si va a renunciar a TLS, es útil comprender cómo funciona. Y todo se trata de un apretón de manos.
Una vez que el cliente y el servidor han acordado usar TLS, negocian una conexión con estado mediante el uso de un protocolo de enlace. [7] Durante este apretón de manos, el cliente y el servidor acuerdan varios parámetros utilizados para establecer la seguridad de la conexión:
- El apretón de manos comienza cuando un cliente se conecta a un servidor habilitado para TLS que solicita una conexión segura y presenta una lista de conjuntos de cifrado admitidos (funciones de cifrado y hash).
- De esta lista, el servidor elige una función de cifrado y hash que también admite y notifica al cliente de la decisión.
- El servidor devuelve su identificación en forma de un certificado digital. [Contradicción] El certificado generalmente contiene el nombre del servidor, la autoridad de certificación de confianza (CA) y la clave de cifrado público del servidor.
- El cliente puede ponerse en contacto con el servidor que emitió el certificado (la CA de confianza como se indica anteriormente) y confirmar la validez del certificado antes de continuar.
- Para generar las claves de sesión utilizadas para la conexión segura, el cliente encripta un número aleatorio con la clave pública del servidor y envía el resultado al servidor. Solo el servidor debería poder descifrarlo con su clave privada.
- A partir del número aleatorio, ambas partes generan material clave para el cifrado y descifrado. [Contradicción] Esto concluye el protocolo de enlace y comienza la conexión segura, que se cifra y descifra con el material clave hasta que se cierra la conexión.
Si alguno de los pasos anteriores falla, el intercambio de señal TLS falla y la conexión no se crea.
Fuente: Wikipedia
Entonces, ¿es posible? Sí. Me enseñaron que todo es posible. Puede ser costoso, pero siempre es posible.
Quiero revelar completamente que NO soy un profesional de seguridad, solo un entusiasta. No recomiendo intentar esto para un proyecto de grado de producción o cualquier cosa que no sea su propia edificación. Debes consultar DEFINITIVAMENTE esta publicación SO que proporciona una excelente explicación sobre los bloqueos de ruta en la configuración de tu propio protocolo de seguridad.
Sin embargo, si quieres seguir adelante, aquí hay algunos pensamientos que te vienen a la mente. Estas son realidades que existirán independientemente de la dirección que eligió para este proyecto.
HTTPS es compatible con todos los principales navegadores modernos. Incluso con esta realidad, los tiempos de carga de HTTPS son más lentos que el HTTP simple. Sin una producción extensa, es muy probable que su implementación alternativa sea una fracción tan segura a la vez que significativamente más lenta. Esto será un inconveniente de cualquier implementación interna a menos que esté utilizando las funciones del navegador, lo que nos lleva a un círculo completo para usar TLS, que es lo que HTTPS moderno utiliza.
Si logras encriptar tu contraseña sin TLS en el lado del navegador usando Javascript de una manera tan impredecible que un ataque MiTM sería difícil, no descanse allí. También debe asegurar los datos que envía de ida y vuelta. De lo contrario, la contraseña cifrada realmente no es relevante. Claro, un atacante podría no saber la contraseña de bobsmith109, pero no la necesita, porque puede oler cada actividad en la red. Él sabe en qué momentos bobsmith109 inicia sesión, probablemente pueda rastrear su IP y cualquier otra pieza sensible de datos que envíe de ida y vuelta.
No importa qué medidas de seguridad tome, hay seguridad en profundidad. Así que una cosa que puedes hacer enseguida es asegurarte de encriptar tus datos en la base de datos y al mismo tiempo requerir contraseñas seguras.
Reitero que no soy un profesional de seguridad y desaconsejo fuertemente esto como algo más que para saciar su curiosidad. Es astronómicamente improbable que pueda crear una alternativa viable a TLS sin un grupo extraordinariamente grande de profesionales de seguridad que contribuyan a un proyecto durante años o décadas, que es lo que SSL / TLS puede presumir. Una vez dicho esto, un buen punto de partida si elige avanzar es observar el modelo de enlace de arriba y ver cómo puede implementar una versión de esto sin TLS.
Sería negligente no compartir en mi publicación que la mayoría de las barreras de la vida real para usar HTTPS se están combatiendo activamente. Uno de los costos más grandes está muy cerca de convertirse en un problema. Saldrá una autoridad certificadora gratuita El 2T 2015 cuenta con el apoyo de algunas armas importantes, incluidas Mozilla y Akamai, por nombrar algunas. Aquí hay un artículo .
Intente esto: en cada solicitud de la página de inicio de sesión, envíe a través de un nonce y una marca de tiempo. Mientras publica en el servidor, envíe los siguientes cuatro detalles:
El nombre de usuario, el nonce y la marca de tiempo en texto plano. A continuación, concatenar lo anterior con un separador (por ejemplo, nueva línea) y cifrar con la contraseña del usuario como cifrado en modo de cifrado de bloque encadenado.
En el extremo del servidor use el nombre de usuario para buscar la contraseña y verificar la cadena encriptada.
Como la contraseña nunca se envía de forma clara, es segura y la marca de tiempo puede utilizarse para evitar volver a enviar los mismos datos.
Para evitar el secuestro de la sesión obteniendo la clave de sesión a través de un ataque man-in-the-middle, la aplicación en el extremo del cliente puede almacenar la contraseña o un hash de la contraseña en la memoria y usarla para generar claves de sesión únicas para validación por servidor.
Echar un vistazo a OAuth 1.0 tampoco es una mala idea.
La mejor solución que he visto para conexiones HTTP algo seguras es usar una implementación de Javascript de md5sum (o algún otro hash) para evitar transmitir la contraseña en texto plano. Puede crear un formulario en el controlador de envío en Javascript que reemplaza el campo de contraseña con un hash del valor original. Esto agrega una cantidad modesta de seguridad a una conexión no segura, pero depende de que Javascript se ejecute en el navegador para funcionar correctamente.
La respuesta corta es que sin un endpoint SSL para el cifrado del punto final, es imposible hacerlo de forma segura ...
Una de las razones principales para esto es que no puede hacer criptografía segura en un navegador. Consulte esta referencia: JavaScript Criptography Considerado Dañino .
Además, no hay manera de que pueda estar seguro de que la fuente de las credenciales es con quién está hablando. Lo que significa que no hay absolutamente ninguna manera sin SSL para estar seguro de que no hay un ataque Man-In-The-Middle en marcha.
Entonces no, no puedes hacerlo.
Además, ni siquiera lo intentes. Obtenga SSL. Puede obtener certificados gratis. Los anfitriones por lo general le darán una IP dedicada por unos $ $ al mes. Y si realmente te importa la seguridad, estarías usando al menos una VM con una dirección IP dedicada de todos modos.
Incluso intentar esto sería Seguridad a través de la oscuridad en el mejor de los casos, y nada en el peor. SSL es un problema resuelto. ¿Por qué no usar esa solución? La seguridad no es algo para adivinar. Usa las técnicas apropiadas. No trates de inventar el tuyo. No funcionará ...
La respuesta es más corta, y si realmente le importa la seguridad, siempre tiene opciones con diferentes niveles de burocracia.
La seguridad de Absolut no existe. La falla número uno siempre está en el lado del cliente, con troyanos y keyloggers . SSL no ayuda con eso.
1) Generadores de fichas : los bancos los usan, la ventisca usa entonces. Puede ser un dispositivo o una aplicación. Bueno ... es caro.
2) Pines de SMS . solución interesante y asequible. Hay muchos buenos precios de sms trnasactional en el mercado y todos tienen un teléfono capaz de recibirlo.
3) Si tiene que usar HTTP, puede forzar un servicio externo de terceros, como google o facebook . Eso es lo mejor que puede hacer sin un generador de fichas.
Puede encriptar la contraseña usando Javascript y descifrarla en el servidor.
Yo recomendaría generar un par de llaves RSA en el servidor, enviar la clave pública junto con un límite de tiempo al navegador, y luego encriptar la contraseña, combinada con la sal, usando la clave pública en Javascript.
Puede encontrar una implementación de RSA en Javascript here
Debería incluir tanto la dirección IP como el hereditario X-FORWARDED-FOR FORWARDED X-FORWARDED-FOR completo en las cookies de autenticación para evitar el robo de cookies detrás de los proxies.
Si está tratando con datos confidenciales, podría generar una clave aleatoria AES en Javascript , luego enviarla al servidor junto con la contraseña cifrada con RSA.
A continuación, puede hacer que toda la aplicación use solicitudes cifradas de AJAX desde una sola página y no use ninguna cookie de autenticación.
Tenga en cuenta que no es posible protegerse contra un ataque man-in-the-mid activo sin SSL. Un atacante activo puede reemplazar completamente su sitio con su propio proxy, y no hay ninguna forma de defenderse de eso. (Dado que no puede haber ningún buen código conocido)
Puede intentar replicarlo en algún punto, mediante el uso de cifrado de clave pública (GPG tal vez) y haciendo uso del almacenamiento en caché del navegador.
Esto no es algo seguro, incluso el simple hecho de instalar SSL no será suficiente para un atacante sofisticado, es necesario utilizar HSTS, fijación de clave pública, etc. para considerar un sitio web seguro hoy en día .
El resto de la respuesta es solo algo para pensar.
- Crea un par de claves públicas y privadas. Mantenga privado uno seguro.
- Cree un archivo js que contenga la clave pública y una función de cifrado, encuentre un algoritmo de cifrado seguro. Esta función debe encriptar una cadena dada (formulario serializado) con una marca de tiempo adicional, para evitar un ataque de replicación.
- Sirva este archivo con
Cache-Control:public, max-age=31536000
encabezado HTTP. Intentamos mitigar cuando el atacante intenta reemplazar el script. El archivo siempre se servirá desde el caché del navegador. - Envíe todos los formularios a través de Javascript, usando la función de
encrypt
. Sirva estos con el mismo encabezado que arriba. - En el lado del servidor,
decrypt
los datos, verifica la marca de tiempo, si aún es válida. ¿Te parece? Si no, deséchalo. - Crea un token de cookies que solo se puede usar una vez durante un período de tiempo muy corto. Si el atacante captura una cookie, no tendrá mucho tiempo para hacer cosas. Sin embargo, si el atacante es lo suficientemente rápido, entonces podría desconectar al usuario original.
- Cambia las cookies con cada respuesta. Pero entonces, ¿qué haces cuando el usuario envía múltiples solicitudes a la vez y luego llegan en el orden inverso? ¿Qué cookie es válida? Esto crea toneladas de problemas a costa de una falsa sensación de seguridad.
Los oyentes no podrán utilizar los datos yendo y viniendo, y no podrán cambiar / inyectar los archivos JS
existentes hasta que el caché caduque / el usuario borre el caché. Sin embargo, cualquier atacante sofisticado puede reemplazar todo el archivo HTML
que descartaría todas las medidas de seguridad que acabo de mencionar. Si puede al menos servir este archivo / formulario a través de HTTPS
, puede salirse con la suya, ponerlos en páginas github o lo que sea. Sin embargo, si coloca el archivo en otro dominio, entonces debe configurar CORS
para el dominio de recepción para que esto funcione.
Otro intento
Contraseñas de un solo uso enviadas al correo electrónico.
- El usuario completa su correo electrónico, hace clic en un enlace que luego envía un enlace a su correo electrónico con un token que les permitirá iniciar sesión.
- El usuario hace clic en el enlace
- El servidor verifica el token y registra al usuario.
- Rueda las cookies como en el ejemplo anterior.
En general, hagas lo que hagas, no es seguro . Dado un atacante rápido y sofisticado, nada se interpone en el camino.
Obtenga SSL, si la infraestructura no lo admite, cámbielo. Si su gerente no cree en SSL, convénzalo. No cree una falsa sensación de seguridad. Proteja los datos de su usuario, según su ubicación, está legalmente obligado a proteger los datos de sus usuarios.
Luego, hablemos sobre cómo hacer que un sitio sea seguro con SSL.
Puede usar la autenticación HTTP Digest , que es compatible con la mayoría de los navegadores y no envía la contraseña de forma clara a través del cable.
La desventaja es el feo cuadro de inicio de sesión mostrado por broswer. Si prefiere quedarse con los formularios, puede implementar exactamente el mismo protocolo que HTTP Digest en su autofinanciación de formularios: envíe los campos ocultos que contengan el reino y el desafío, y pida al cliente que agregue el código JavaScript y calcule el resumen. De esta forma, utilizará un protocolo de intercambio bien conocido y comprobado, en lugar de usar uno propio.
HTTP Digest solo requiere operaciones hash.
Si no puede usar HTTPS o no quiere usar HTTPS, considere usar jCryption . jCryption ofrece cifrado para los datos que se envían a través de solicitudes HTTP (POST, GET, etc.).
Puede probar la técnica aquí: http://www.jcryption.org/#examples
Si está utilizando Firebug, verá que todos los datos están encriptados.
Tiene la biblioteca jQuery para encriptar los datos en el front-end y una biblioteca PHP para descifrar los datos en el back-end.
Supongo que te importa la transmisión segura de la contraseña al servidor. Mi respuesta es: no transmita contraseñas al servidor :)
De hecho, no puede transmitir nada desde el navegador (usuario) al servidor para autenticar al usuario, ya que un atacante que está espiando el tráfico http también podría retransmitir los datos y autenticarse.
Propuesta:
La solución obvia sería usar una autenticación de transacción de una sola dirección que se origina desde el servidor; como un número de transacción que solo se puede usar una vez. Eventualmente, aún necesita un canal seguro una vez para sincronizar la lista de números de transacción con el usuario.
Puede usar algo autenticador de google , sin embargo, necesita un canal seguro una vez para configurar parámetros en cualquier lado. Si considera que el correo electrónico es seguro, sería un camino por recorrer.
Tengo el mismo problema en un sistema mío. He tomado medidas para tratar de aumentar la seguridad sin comprometer la experiencia del usuario con mecanismos intrincados. Lo que noté fue que la gran mayoría de los usuarios iniciaron sesión desde la misma máquina usando el mismo navegador, (pero no necesariamente la misma dirección IP), o desde un par de navegadores (por ejemplo: escritorio o móvil). Decidí que podría usar esto para identificar un patrón.
1) Durante el registro, los usuarios deben tener contraseñas seguras (para evitar ataques de diccionario), una pregunta / respuesta de seguridad y verificación de correo electrónico estándar (como prueba de persona real)
2) Durante el inicio de sesión, después de 5 intentos de inicio de sesión fallidos (no antes), se muestra un captcha para evitar ataques de fuerza bruta.
3) Finalmente, creé un hash de partes de la cadena de agente de usuario después de un inicio de sesión exitoso, que contenía el sistema operativo de los usuarios, el navegador (generalmente no versiones) y el lenguaje, formando una especie de contraseña secundaria. Si el hash de useragent es significativamente diferente en el siguiente inicio de sesión, se le pide al usuario que responda la pregunta de seguridad. Luego, si se responde satisfactoriamente, la nueva cadena de UA se modifica y se agrega a su lista de "máquinas seguras", de modo que no se vuelvan a preguntar desde esta máquina. Esto es similar a un mecanismo empleado por el sistema de juego Steam.
Esto ha estado en uso durante más de un año con mucho éxito con aproximadamente 700 usuarios y tenía el beneficio adicional de evitar el "uso compartido de inicio de sesión", ¡un problema en el que varios usuarios usaban las mismas credenciales para mayor comodidad!
Utilice los mecanismos de hash para almacenar la contraseña y compare siempre la contraseña hash entonces nadie sabe la contraseña real, incluso usted. Es muy simple pero es efectivo. Sin embargo, nada es completamente seguro y hay algunas formas de romper las capas de seguridad.