¿Mi sistema de autenticación sin sesión es seguro?

10

Por lo tanto, he creado un sistema de autenticación. Vertido sobre él para cualquier tipo de fallas de seguridad y probé la mierda fuera de él. Creo que es bastante seguro, pero hay un aspecto de diseño diferente "diferente" que no es habitual en un sistema de autenticación web.

Básicamente, quería que fuera posible realizar la autenticación sin hacer un seguimiento de la sesión de cada usuario. Esto significa menos carga en la base de datos y trivial para escalar y almacenar en caché. Aquí están los "secretos" guardados por el servidor:

  • Se mantiene una clave privada en el código fuente de la aplicación
  • Se mantiene una sal generada aleatoriamente para cada usuario

Para que no tenga sesión, pero no es fácil falsificar las cookies, este es el formato de mis cookies

expires=expiretimestamp
secret=hash(privatekey + otherinfo + username + hashedpassword + expires)
username=username

(con otherinfo son cosas como la dirección IP, información del navegador, etc. y con hashedpassword=hash(username + salt + password + privatekey)

Tengo entendido que la creación de cookies de inicio de sesión (sin descifrar las contraseñas) requiere:

  1. Acceso al código fuente de la aplicación, o una forma de engañarlo para que escupa la clave privada
  2. Acceso de solo lectura a la base de datos para obtener el salt y la contraseña de hash

Mientras que el método de sesión tradicional requiere:

  1. Acceso de escritura y lectura a la base de datos (para inyectar la sesión o engañar a la aplicación web para que lo haga por usted)
  2. Posiblemente el acceso al código fuente depende de cómo funciona

De todos modos, ¿esto parece demasiado inseguro para alguien? ¿Hay alguna manera de mejorarlo y hacerlo más seguro (manteniendo el modelo sin estado / sin sesión)? ¿Hay algún sistema de autenticación existente que use este modelo sin estado?

Además, el método de hashing puede ser básicamente cualquier cosa, desde SHA256 hasta Blowfish

    
pregunta Earlz 29.11.2012 - 22:08
fuente

3 respuestas

14

Su concepto básico no es nuevo: desea tener algún estado asociado con el usuario, pero no desea almacenar ese estado. En su lugar, lo almacena en el cliente (en una cookie). Como desea protegerse contra las alteraciones de dicho estado (por ejemplo, un cliente que crea una cookie desde cero), necesita una verificación de integridad, como Código de autenticación del mensaje . Su construcción con una función hash es un MAC crudo. Sucede que es un MAC débil con las funciones hash habituales, debido al ataque de extensión de longitud .

Si desea un MAC, use uno fuerte, y eso significa HMAC . Es estándar y está muy extendido.

Por supuesto, el almacenamiento de la clave secreta (para cálculos de MAC) es un punto delicado. Algo incrustado en el "código fuente" de la aplicación existe como un archivo que (por naturaleza) la aplicación puede leer, lo que lo hace vulnerable a las vulnerabilidades que obtienen acceso de lectura ilegal a archivos arbitrarios. Sería mejor (pero más difícil) organizar que la clave MAC la obtenga dinámicamente mediante la aplicación a través de algún protocolo de comunicación local (la aplicación se comunica con un servidor local, que proporciona la clave solo a la aplicación); de esa manera, la clave solo existiría en la RAM de la aplicación, no como un archivo legible con los derechos de acceso de la aplicación. No sería una protección absoluta (si su servidor se hackea a fondo, bueno, eso es todo) pero sería más fuerte en la práctica.

Veo que incluyes la contraseña con hash en los datos que están en MAC. Esto es un poco raro; ya tiene el MAC como autenticación: el MAC demuestra que los datos de la cookie son auténticos, por lo que no es necesario realizar una autenticación adicional.

Blowfish no es una función hash; es un cifrado de bloque (o un tipo de pez ) y, como tal, no se puede usar para el hashing a menos que se modifique considerablemente, lo que significaría criptografía casera, y eso no es una buena idea.

Si está descargando el estado en el cliente, es posible que desee descargar el estado que el propio cliente no debería saber. Esto significa que también puede necesitar cifrado. La combinación de cifrado y MAC de forma segura no es tan fácil como parece; hay modos para eso . Recomiendo EAX .

Tenga en cuenta que no mantener el estado lo hace inherentemente débil contra ataques de repetición . Eso es inevitable. Puede minimizar el daño utilizando rangos de validez cortos (por ejemplo, una cookie caduca en 15 minutos).

    
respondido por el Thomas Pornin 30.11.2012 - 13:27
fuente
2

Este sistema propuesto es un controlador de sesión que se usa para mantener un estado autenticado y su método de creación de tokens de sesión es inseguro.

Por ejemplo, al usar la inyección SQL puede leer la mayoría de los datos secretos de la base de datos. Si está utilizando MySQL SQL Injection puede usarse para leer archivos usando la función load_file () que podría usarse para leer el secreto de un archivo de configuración.

En general, no debes reinventar la rueda al construir un sistema. Estoy seguro de que su plataforma viene con un controlador de sesión seguro porque casi todas las aplicaciones web necesitarán una.

Los ID de sesión deben ser valores puramente aleatorios y una combinación de entropía como / dev / urandom es una excelente opción. El hecho de que esté utilizando el controlador de sesión de la plataforma no significa que esté configurado correctamente. Recomiendo leer la Hoja de referencia de administración de sesiones de OWASP .

    
respondido por el rook 29.11.2012 - 22:15
fuente
2
  

Para que no tenga sesión, pero no es fácil falsificar las cookies, este es el formato de mis cookies

Lo que describe no es sin sesión, es solo que el estado de autenticación se mantiene en el navegador en lugar del servidor.

Incluso para un sitio solo SSL, es una buena idea tratar de detectar el secuestro y la fijación de la sesión (para la fijación, el tipo de explotaciones disponibles es más restringido ya que, presumiblemente, la autenticación está directamente relacionada con la administración de la sesión), lo que significa el almacenamiento del lado del servidor de datos. / p>

La autenticación no es muy útil sin autorización (por favor, no me digas que tu autorización está incorporada directamente en tu código), que de nuevo depende de la información del lado del servidor.

Aún debe volver a generar el hash para verificar cada solicitud o almacenar el hash en una tabla de búsqueda, lo que significa recuperar datos en el servidor.

Luego, si tiene algún tipo de procesamiento de datos, además de los datos transaccionales, debe tener prevención de CSRF, que generalmente se implementa mediante el almacenamiento del lado del servidor de datos.

No veo cómo ha reducido la carga de trabajo en comparación con el uso de una sesión web convencional. Si simplemente incluyó el nombre de usuario, el tiempo de caducidad y el hash del nombre de usuario y el tiempo de caducidad, entonces sí, podría basarse en el valor de la cookie como una prueba de identidad equivalente a una sesión web convencional, pero esto solo permite un muy modelo de autorización / acceso limitado.

    
respondido por el symcbean 01.12.2012 - 01:03
fuente

Lea otras preguntas en las etiquetas