Pregunta

Django viene con middleware de protección CSRF , que genera un token único por sesión para usar en formularios. Analiza todas las POST solicitudes entrantes para obtener el token correcto y rechaza la solicitud si 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 enturbiar el marcado insertando el token como un valor oculto. Creo que una buena manera de hacer esto es exponer una vista como /get-csrf-token/ para devolver el token del usuario, confiando en las reglas de scripting entre sitios del navegador para evitar que los sitios hostiles lo soliciten.

¿Es esta una buena idea? ¿Hay mejores maneras de protegerse contra los ataques CSRF y al mismo tiempo permitir las solicitudes AJAX?

¿Fue útil?

Solución

Si sabe que va a necesitar el token CSRF para solicitudes AJAX, siempre puede incrustarlo en el HTML en alguna parte; entonces puedes encontrarlo a través de Javascript atravesando el DOM. De esta manera, aún 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.

Otros consejos

ACTUALIZACIÓN : lo siguiente era cierto y debería ser cierto si todos los navegadores y complementos se implementaron correctamente. Desafortunadamente, ahora sabemos que no lo son, y que ciertas combinaciones de complementos y redireccionamientos del navegador pueden permitir que un atacante proporcione encabezados arbitrarios en una solicitud de dominio cruzado. Desafortunadamente, esto significa que incluso las solicitudes AJAX con & Quot; X-Requested-With: XMLHttpRequest & Quot; El encabezado ahora debe estar protegido por CSRF. Como resultado, Django ya no exime las solicitudes de Ajax de la protección CSRF .

Respuesta original

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

Esto solo es válido si en realidad está verificando el encabezado X-Requested-With del lado del servidor para " XMLHttpRequest " valor (que hace Django), y solo exime las solicitudes AJAX reales del escaneo CSRF.

Cancele eso, estaba equivocado. (Véanse los comentarios). Puede evitar el exploit asegurándose de que su JSON siga las especificaciones: siempre asegúrese de devolver un objeto literal como el objeto de nivel superior. (No puedo garantizar que no habrá más exploits. ¡Imagine un navegador que proporciona acceso al código fallido en sus eventos window.onerror!)

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

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top