Protección CSRF y aplicaciones de una sola página

24

Estoy en el proceso de escribir una aplicación web de cliente grueso con Angular.js (aplicación de una sola página) y me preguntaba cuáles son las mejores prácticas para asegurar la aplicación con un token CSRF.

¿Debo enviar un token CSRF cuando la aplicación se carga por primera vez y luego volver a usar ese token en cada solicitud? ¿Debo tener un mecanismo para actualizar el token? ¿Hay otras protecciones en lugar de un token CSRF que tendría más sentido para una aplicación de una sola página?

    
pregunta Olivier Lalonde 25.05.2013 - 18:31
fuente

2 respuestas

16

Bueno, aquí es cómo terminé implementando CSRF:

En la primera solicitud, establece un token CSRF como una cookie. Todas las solicitudes subsiguientes de AJAX incluyen el token CSRF como un encabezado HTTP X-CSRF-Token .

Django tiene una buena documentación sobre cómo hacer esto limpiamente con jQuery: enlace

Editar: un enfoque alternativo incluye listas blancas que contienen el encabezado X-Requested-With . Parece que eso es Pero como @damio señaló a continuación, el X-Requested-With es un peligro para la seguridad, Django and Rails revertido volver a no usarlo y forzar un token.

    
respondido por el Olivier Lalonde 26.05.2013 - 05:40
fuente
13

Estás de suerte! Hace aproximadamente 2 semanas me hicieron la misma pregunta y, después de rascarme la cabeza, se me ocurrió lo siguiente. Tenga en cuenta que esto no está bien revisado por pares, así que veremos cómo van los comentarios y las votaciones. Personalmente, creo que es una buena técnica.

1. Primera solicitud

Una vez que reciba la primera solicitud para cargar su aplicación, genere un identificador aleatorio seguro y guárdelo en una variable de sesión en el servidor, luego envíelo al cliente. Lo incrusté en la página justo antes de </body> .

<script>setToken('<% print SESSION[TOKEN] %>');</script>
</body>

Tu setToken() asignaría el valor del token a la variable en la que mantendrías el token.

2. Solicitudes posteriores

Con cada solicitud, agregarías ese token a la lista de parámetros, como token=TOKEN , y el servicio lo compararía con el almacenado en la variable de sesión.

3. Actualizar el token

No es realmente obligatorio, pero es una buena idea actualizar el token de vez en cuando, por ejemplo, 15 minutos. Cuando recibe una solicitud después de que caduque el token (tiene el tiempo de caducidad en la variable de sesión), responde a ella normalmente (actúe de manera optimista) pero en la respuesta le dice al cliente que el token anterior ha caducado y debería comenzar a usar el uno nuevo.

El cliente reacciona a eso diciéndole al servidor que ahora conoce el nuevo token, una vez que el servidor recibe esa solicitud, comienza a usar el nuevo token y responde al cliente con un mensaje OK, una vez que el cliente recibe 200 OK significa que ambos están sincronizados y el cliente comienza a usar el nuevo token.

Nota: Un elemento clave en el proceso es el uso de HTTPS. No quieres que un hombre en el medio huela la ficha. Pero, de nuevo, un MitM podría detectar las cookies y secuestrar la sesión de todos modos.

    
respondido por el Adi 25.05.2013 - 20:47
fuente

Lea otras preguntas en las etiquetas