Mecanismo de protección CSRF personalizado sin tokens persistentes

0

He tenido esta funcionalidad (protección csrf) desde hace bastante tiempo. Lo que nunca me gustó de esto es que guardó los tokens csrf en el archivo de sesión. Si bien puede que no sea un problema real, lo veo como un problema, ya que eventualmente los tokens pueden acumularse, así que necesito utilizar un mecanismo de Gc y hacer un seguimiento de lo que se emitió cuando todo parece demasiado para mí.

Así que pasé los últimos días trabajando para mejorar esta "imperfección" y esto es lo que he encontrado. No publicaré ningún código real, solo explicaré la idea.

Cuando se emite un formulario, de forma predeterminada se genera un token. El token consta de algunos datos únicos para el usuario, como el ID de sesión o el ID de usuario, combinados con la cadena de fecha y hora actual en el formato YmdHi . Todo esto se cifra mediante password_hash y he pensado en ofuscar el hash mediante el intercambio de partes del mismo, pero aún no lo he hecho.

La validación fue un poco complicada y resultó ser una gran decepción. Para validar un token, creo un bucle que contiene la misma información sobre el usuario con la fecha y resta 1 minuto en cada iteración. El número de iteraciones es igual a la cantidad de minutos durante los cuales el token es válido, que no está almacenado en el token, por lo tanto, todos los tokens deben ser válidos durante el mismo periodo de tiempo, lo que no me parece una desventaja todavía. / p>

Quiero preguntarle si ve algún posible fallo o vulnerabilidad con este concepto.

El único problema posible que veo es que el servidor no guarda los tokens, por lo que, en teoría, cualquiera puede armar un token válido. Sin embargo, creo que es muy improbable que alguien pase días recolectando tokens y tenga un superordenador. en su sótano para ejecutar analistas estadísticos, lo que de nuevo no es garantía de que puedan descifrar el cifrado.

De todos modos, supongo que debería dejar de exponer mi incompetencia y dejar que la gente inteligente decida qué pasa.

    
pregunta php_nub_qq 29.05.2015 - 21:31
fuente

4 respuestas

2

Personalmente, nunca he visto a alguien lanzar su propia alternativa a un estándar de la industria para la seguridad y hacer que se convierta en una solución aceptable. Una frase que escucho mucho en la comunidad de seguridad es "No hagas rodar la tuya".

Al leer lo que estás haciendo, parece que puedes ser demasiado inteligente para tu propio bien. Esto parece una solución compleja que podría ser menos segura que simplemente crear un token CSRF. Si alguien hereda tu código, probablemente explotará su cabeza.

No estoy seguro de dónde está almacenando el token que está creando, pero si está en una cookie no hay protección alguna. Si está colocando su token en un campo oculto en el formulario, entonces esencialmente está usando una versión extrañamente modificada de envíe doble la protección CSRF de la cookie .

Mi consejo: no sigas por este camino. En el mejor de los casos será más complejo y seguro. En el peor de los casos, será más complejo y no funcionará.

    
respondido por el Abe Miessler 29.05.2015 - 22:15
fuente
1

También creo que puedes estar sobre pensando / diseñando aquí. Me parece que combina la autorización de sesión con la protección CSRF. No soy un programador de PHP, pero en todos los lenguajes y marcos que he usado, este nivel de protección ya está disponible de alguna forma. Probablemente sea mejor usar una solución establecida en lugar de utilizar la propia.

La mayoría de las soluciones que he visto no generan nuevos tokens para cada solicitud. Por lo general, hay un solo token por sesión y se almacena con los datos de la sesión, por lo que no hay problemas de GC. Todo lo que realmente debería estar haciendo es verificar que la respuesta proviene del mismo cliente al que se envió el formulario. Se suele suponer que la sesión ya está autorizada. Si está preocupado por la autorización de la sesión, entonces tiene mayores problemas porque el atacante podría simplemente secuestrar la sesión, en cuyo caso, obtendrán un token 'legítimo' cuando soliciten el formulario.

    
respondido por el Tim X 30.05.2015 - 02:09
fuente
1

Si desea evitar el almacenamiento adicional en la base de datos o la sesión de su aplicación, ¿por qué no simplemente usa Doble método de prevención de cookies .

Aquí simplemente envía un valor de cookie duplicado a través de otro mecanismo junto con cada solicitud, como dentro de un campo de formulario oculto.

Por ejemplo, genere un valor aleatorio criptográficamente seguro con 32 bits de entropía. Almacene este valor en una cookie llamada csrftoken y en cada formulario como un campo oculto llamado csrftoken . Cuando se envía cada formulario, verifica que el csrftoken enviado desde ambos mecanismos de entrega coincida.

No use la ID de sesión para esto: la página OWASP recomienda usar un valor separado de la ID de sesión porque brinda protección adicional contra la pérdida de la ID de sesión. Proteja su identificación de sesión tanto como sea posible y no exponerla innecesariamente ayudará a mantener la administración segura de la sesión. Recuerde que no tiene que almacenar este lado del servidor de token adicional. Todo lo que está haciendo en cuanto a funcionalidad es verificar que el token POSTed coincida con la cookie, realmente no importa el valor que tenga para su servidor. Lo único que importa es que se envíe el mismo valor a través de una cookie que a través del formulario, ya que un atacante no sabría este valor y, por lo tanto, no podría enviarlo ellos mismos.

Tenga en cuenta que no necesita un token CSRF por formulario. La única forma en que un atacante va a recuperar un token es a través de otra vulnerabilidad (como XSS). Y si pueden realizar XSS, ya han derrotado este tipo de protección CSRF. Sin embargo, debe volver a generar el token para cada nueva sesión para evitar cualquier tipo de fuerza bruta persistente en su contra.

    
respondido por el SilverlightFox 30.05.2015 - 12:50
fuente
0

Ha visto que hay un problema cuando usa el tiempo como parte del valor cuando crea un hash: el tiempo cambia constantemente. Pero hay alguna utilidad en usarlo en un token csrf. La solución para permitir pequeñas variaciones es no hash los valores para obtener el token, sino usar el cifrado simétrico de una representación del tiempo junto con algunos otros valores.

Sin embargo, el uso de sesiones suele ser más sensato. Y si tiene 'usuarios', 'contraseñas', entonces, por definición, tiene una sesión y, por lo tanto, debe estar haciendo la administración del estado. Realmente no hay razón para no usar la sesión para mantener los tokens csrf.

    
respondido por el symcbean 30.05.2015 - 16:27
fuente

Lea otras preguntas en las etiquetas