¿Son los servicios web JSON vulnerables a los ataques CSRF?

82

Estoy construyendo un servicio web que utiliza exclusivamente JSON para su contenido de solicitud y respuesta (es decir, sin cargas útiles codificadas en forma).

¿Es un servicio web vulnerable al ataque CSRF si se cumple lo siguiente?

  1. Cualquier POSTsolicitud sin un objeto JSON de nivel superior, por ejemplo, {"foo":"bar"}será rechazada con un 400. Por ejemplo, una POSTsolicitud con el contenido 42sería rechazada.

  2. Cualquier POSTsolicitud con un tipo de contenido diferente a application/jsonse rechazará con un 400. Por ejemplo, una POSTsolicitud con un tipo de contenido application/x-www-form-urlencodedse rechazará.

  3. Todas las solicitudes GET serán seguras y, por lo tanto, no modificarán ningún dato del lado del servidor.

  4. Los clientes se autentican a través de una cookie de sesión, que el servicio web les proporciona después de proporcionar un par de nombre de usuario / contraseña correcto a través de un POST con datos JSON, por ejemplo {"username":"[email protected]", "password":"my password"}.

Pregunta auxiliar: ¿Son PUTy las DELETEsolicitudes alguna vez vulnerables al CSRF? Lo pregunto porque parece que la mayoría (¿todos?) Los navegadores no permiten estos métodos en formularios HTML.

EDITAR: elemento agregado # 4.

EDITAR: Muchos buenos comentarios y respuestas hasta ahora, pero nadie ha ofrecido un ataque CSRF específico al que este servicio web sea vulnerable.

djsmith
fuente
Tokenice sus solicitudes a través de la sesión y los valores emparejados de cookies, desinfecte las directivas que esté activando a través del JSON enviado, agregue sal para darle más sabor
Brandt Solovij
No creo que haya suficiente información aquí para proporcionar una buena respuesta. ¿Qué método de autenticación está utilizando? ¿Quiénes son los consumidores previstos del servicio web (es decir, usuarios de un sitio en el mismo host que su servicio?)
McGarnagle
1
Todas sus validaciones actuales son perfectamente sensatas y limitan su superficie de ataque, pero en realidad no abordan nada que ver con la vulnerabilidad CSRF.
Cheekysoft
2
@ DavidBalažic ¿Qué vector? Si está hablando de AJAX, las políticas del mismo origen lo evitarán.
djsmith

Respuestas:

73

Forjar solicitudes CSRF arbitrarios con los tipos de medios arbitrarios es efectiva sólo es posible con XHR, porque un método de formulario se limita a GET y POST y un cuerpo del mensaje POST del formulario también está limitada a los tres formatos application/x-www-form-urlencoded, multipart/form-dataytext/plain . Sin embargo, con la codificación de datos del formulario text/plain, todavía es posible falsificar solicitudes que contengan datos JSON válidos .

Entonces, la única amenaza proviene de los ataques CSRF basados ​​en XHR. Y esos solo tendrán éxito si son del mismo origen, por lo que básicamente de su propio sitio de alguna manera (por ejemplo, XSS). Tenga cuidado de no confundir la desactivación de CORS (es decir, no configurar Access-Control-Allow-Origin: *) como protección. CORS simplemente evita que los clientes lean la respuesta. El servidor aún envía y procesa toda la solicitud.

Gumbo
fuente
9
Como comenté en su respuesta vinculada, afirmo que text / plain se puede usar para la falsificación de JSON si el servidor no requiere application / json, usando técnicas similares a pentestmonkey.net/blog/csrf-xml-post-request .
8
Esa respuesta es correcta hasta hoy, pero probablemente pronto estará equivocada. W3C está considerando agregar enctype = "application / json" al estándar HTML: darobin.github.io/formic/specs/json Así que no confíe en el tipo de cuerpo POST para una seguridad duradera, use un token anti-CSRF.
LordOfThePigs
@LordOfThePigs Forjar JSON válido ya es posible con text / plain .
Gumbo
@Gumbo es correcto, pero actualmente no puede establecer el tipo de enctipo application/jsonque se usa para mantener a raya los ataques CSRF en esta respuesta. El estándar propuesto le permitirá establecer enctype application/json, lo que anularía las verificaciones de tipo de contenido descritas en la respuesta y abriría la aplicación a CSRF.
LordOfThePigs
10
Parece que el borrador se adelanta a este ataque. La sección 5 especifica que las application/jsonpublicaciones de formulario deben cumplir con la misma política de origen, lo que significa que el ataque no es más fuerte que XHR.
James_pic
3

Sí, es posible. Puede configurar un servidor atacante que devolverá una redirección 307 al servidor de destino a la máquina víctima. Necesita usar flash para enviar el POST en lugar de usar Form.

Referencia: https://bugzilla.mozilla.org/show_bug.cgi?id=1436241

También funciona en Chrome.

Timothy Leung
fuente
1

Es posible hacer CSRF en servicios Restful basados ​​en JSON usando Ajax. Probé esto en una aplicación (usando Chrome y Firefox). Debe cambiar contentType a text / plain y dataType a JSON para poder realizar una solicitud de verificación previa. Luego puede enviar la solicitud, pero para enviar datos de sesión, debe configurar el indicador withCredentials en su solicitud ajax. Discuto esto con más detalle aquí (se incluyen referencias):

http://wsecblog.blogspot.be/2016/03/csrf-with-json-post-via-ajax.html

Filip Waeytens
fuente
Eso es innecesario. Si el servidor lee las solicitudes de texto sin formato como JSON, un formulario codificado como texto sin formato es suficiente para falsificar dicha solicitud, como ha mencionado Gumbo. Los servidores API simplemente deberían rechazar las solicitudes de texto sin formato.
Franklin Yu
-1

Tengo algunas dudas sobre el punto 3. Aunque se puede considerar seguro, ya que no altera los datos del lado del servidor, los datos aún se pueden leer y el riesgo es que puedan ser robados.

http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/

panteo
fuente
1
Eso solo funciona si el objeto de nivel superior devuelto por la API es una matriz JSON, ya que Javascript permite anular el constructor de matriz. Un objeto de nivel superior es seguro. Más en flask.pocoo.org/docs/0.10/security/#json-security .
btubbs
Según el propio autor, " no creo que ningún navegador moderno tenga este defecto ".
Franklin Yu
-6

¿Es un servicio web vulnerable al ataque CSRF si se cumple lo siguiente?

Si. Sigue siendo HTTP.

¿Son las solicitudes PUT y DELETE vulnerables a CSRF?

si

parece que la mayoría de los navegadores (¿todos?) no permiten estos métodos en formularios HTML

¿Crees que un navegador es la única forma de realizar una solicitud HTTP?

symcbean
fuente
3
El hecho de que un servicio utilice HTTP no lo hace vulnerable a CSRF. ¿Puede identificar un vector de ataque CSRF real al que este servicio, como se describe, es vulnerable? Y, por supuesto, no creo que un navegador sea la única forma de realizar una solicitud HTTP, pero el navegador es el más común (¿solo?) Para que un usuario sea engañado para que realice una solicitud falsificada entre sitios que no hizo. esperar.
djsmith
En otras palabras, muéstreme un vector de ataque CSRF específico que usa PUT para engañar a un usuario para que envíe una solicitud PUT a mi servicio web (como se describe). Creo que no es posible.
djsmith
@symcbean: ¿Podrías publicar referencias o defender tu respuesta? No he votado sobre esta respuesta, me gustaría que interviniera primero. Gracias.
dotancohen
¿Está Google caído de nuevo? Dejando a un lado el tipo de contenido, las versiones antiguas de Flash (las versiones más recientes de Flash tienen un modelo de control de dominios cruzados, pero es diferente del HTML5). ¿ Qué tal el contrabando de jar? Pseudo-flaw.net/content/web-browsers/corrupted -jars (Java se ejecuta en contexto activo pero puede invocar javascript en contexto pasivo). Luego están los ataques de
revinculación
Los complementos del navegador pueden leer su cookie CSRF y enviar cualquier encabezado que deseen, por lo que incluso los mecanismos de aplicación CSRF estándar de facto son vulnerables a un complemento del navegador malicioso.
djsmith