ajax django security csrf

ajax - csrf token laravel



¿Es seguro exponer el token de protección CSRF de una sesión? (3)

Django viene con el middleware de protección CSRF , que genera un token único por sesión para usar en formularios. Escanea todas las solicitudes POST entrantes para el token correcto y rechaza la solicitud si el token falta o no es válido.

Me gustaría usar AJAX para algunas solicitudes POST, pero dichas solicitudes no tienen el token CSRF disponible. Las páginas no tienen elementos <form> para enganchar y prefiero no ensuciar el marcado insertando el token como un valor oculto. Me parece que una buena forma de hacerlo es exponiendo un dispositivo como /get-csrf-token/ para devolver el token del usuario, confiando en las reglas de scripts entre sitios del navegador para evitar que los sitios hostiles lo soliciten.

¿Es esta una buena idea? ¿Hay mejores formas de protegerse contra los ataques de CSRF al mismo tiempo que se permiten las solicitudes de AJAX?


Cancelar eso, estaba equivocado. (Consulte los comentarios.) Puede evitar el exploit asegurándose de que su JSON sigue la especificación: Siempre asegúrese de devolver un objeto literal como el objeto de nivel superior. (No puedo garantizar que no haya más exploits. Imagine un navegador que proporciona acceso al código fallido en su ventana. ¡Eventos de error!)

No puede confiar en las reglas de secuencias de comandos entre sitios para mantener las respuestas AJAX privadas. Por ejemplo, si devuelve el token CSRF como JSON, un sitio malicioso podría redefinir el constructor String o Array y solicitar el recurso.

bigmattyh es correcto: debe insertar el token en algún lugar del marcado. Alternativamente, puede rechazar cualquier POST que tenga un referer que no coincida. De esta forma, solo las personas con firewalls de software excesivamente celosos serán vulnerables a CSRF.


Si sabe que va a necesitar el token CSRF para solicitudes AJAX, siempre puede incrustarlo en el HTML en alguna parte; luego puedes encontrarlo a través de Javascript atravesando el DOM. De esta manera, todavía tendrá acceso al token, pero no lo expondrá a través de una API.

Para decirlo de otra manera: hágalo a través de las plantillas de Django, no a través del despachador de URL. Es mucho más seguro de esta manera.


ACTUALIZACIÓN : Lo siguiente era verdadero, y debería ser cierto si todos los navegadores y complementos se implementaran correctamente. Desafortunadamente, ahora sabemos que no lo están, y que ciertas combinaciones de complementos y redireccionamientos del navegador pueden permitir que un atacante proporcione encabezados arbitrarios en una solicitud entre dominios. Desafortunadamente, esto significa que incluso las solicitudes AJAX con el encabezado "X-Requerido-Con: XMLHttpRequest" ahora deben estar protegidas por CSRF. Como resultado, Django ya no exime las solicitudes Ajax de la protección CSRF .

Respuesta original

Vale la pena mencionar que no es necesario proteger las solicitudes AJAX de CSRF, ya que los navegadores no permiten las solicitudes AJAX entre sitios. De hecho, el middleware Django CSRF ahora automáticamente exime a las solicitudes AJAX del escaneo de token CSRF .

Esto solo es válido si está realmente comprobando que X-Requerido-Con encabezado del lado del servidor para el valor "XMLHttpRequest" (que hace Django), y solo exime solicitudes AJAX reales del escaneo CSRF.