Trabajo para una universidad, donde formo parte del equipo responsable de integrar un Sistema de Gestión de Aprendizaje SaaS (por ejemplo: Moodle, Canvas) con el resto de los sistemas de la universidad.
Hace dos meses, identifiqué un ataque CSRF, disponible para cualquier persona que pueda agregar materiales del curso al sistema (en su mayoría profesores, pero también a otros profesores académicos y tutores). El problema es que los materiales del curso pueden contener javascript y cualquier usuario administrador que vea los materiales del curso (por ejemplo, en respuesta a una solicitud de soporte) ejecutará el javascript. Como el sistema ahora cuenta con una API REST (¡documentada públicamente!), Es posible que dicho javascript, entre otras cosas, haga que cualquier usuario sea un administrador del sistema. En particular, el sitio web utiliza la API REST en todo momento, lo que significa que javascript debe poder realizar llamadas a la API. He desarrollado demostraciones de explotación funcional, por lo que estoy seguro de que funciona y de lo fácil que es hacerlo.
Se lo informé al proveedor, y su respuesta inmediata fue: 'Los profesores son usuarios de confianza, esto funciona como está diseñado'. A lo que mi respuesta furiosa fue "No confío en que los profesores sean administradores de sistemas". De acuerdo con una consulta de base de datos simple, tenemos unos ~ 4000 usuarios en el sistema que podrían cargar materiales de javascript, de un total de ~ 50000 usuarios. Dos meses después, aún siguen con su respuesta original.
Estoy un poco preocupado por el sistema de mi propia institución: implementé algunos scripts de monitoreo externos para decirme si aparecen administradores inesperados y tenemos copias de seguridad fuera de línea, que es casi todo lo que puedo hacer. Sin embargo, también me molesta que este exploit afecte a todas las instalaciones de este tipo en todo el mundo, y es un sistema comúnmente ejecutado (probablemente > 1000 instancias).
Como esto es SaaS, no tenemos suficiente acceso al sistema para poder bloquearlo nosotros mismos.
Tengo un grupo de preguntas relacionadas:
- ¿Este ataque es aceptable o, al menos, común entre los sistemas de grandes empresas?
- Creo que envolver el contenido generado por el usuario en un iframe con el atributo sandbox bloquearía este ataque (siempre que los administradores usen navegadores actualizados), utilizando CORS para evitar solicitudes a la API REST. ¿Es esto seguro? ¿De lo contrario es posible hacer seguro el javascript subido por el usuario?
- Si el proveedor se niega a arreglarlo, ¿cuáles son mis próximos movimientos? ¿Se recomienda la divulgación pública, dado que es bastante fácil de explotar una vez que se conoce?
EDIT : para responder a los comentarios:
Admito que estoy un poco confuso sobre la diferencia entre csrf y xss, a pesar de leer artículos sobre el mismo. Por esta definición es XSS en el sentido de que 'ejecuta de alguna manera un script' , pero es CSRF en el sentido de que tiene que 'usar una sesión / cookie ya registrada de la víctima'. Además, el token es el token que es clave para el exploit.
Aquí hay algunos detalles más sobre cómo funciona la explotación / mitigación, por (2). Aunque tienes razón; Esto realmente debería ser una pregunta separada.
El ataque consiste en incluir una solicitud fetch
en el javascript proporcionado que realiza una solicitud PATCH REST contra la API apropiada, en cuyo caso la cookie de la víctima se usa como autenticación para la API. Las solicitudes que no son GET requieren un encabezado personalizado (un token 'xsrf'), pero es posible que el javascript proporcionado raspe ese token de otra página.
En cuanto a la mitigación propuesta: los contenidos del curso, incluidos todos los javascript proporcionados por el usuario, están actualmente envueltos en un solo div
. Propongo reemplazar el div
con un iframe
que recupera los contenidos del usuario por separado (o usa un srcdoc
), y tiene un atributo de caja de arena sin el indicador allow-same-origin
. Eso significaría que la secuencia de comandos no tendría acceso a la cookie de autenticación y, de todos modos, no podría realizar solicitudes de recuperación a la API debido a CORS.