Protección CSRF con encabezados personalizados (y sin validar el token)

53

Para un REST-api parece que es suficiente verificar la presencia de un encabezado personalizado para proteger contra ataques CSRF, por ejemplo. cliente envía

"X-Requested By: whatever"

y el servidor comprueba la presencia de "X-Requested-By" y descarta la solicitud si no se encuentra el encabezado. El valor del encabezado es irrelevante. Así es como funciona CsrfProtectionFilter de Jersey 1.9 y se describe en esta publicación del blog: enlace . La publicación del blog también contiene enlaces a los documentos de la NSA y Stanford que indican que el encabezado personalizado en sí es suficiente protección:

  

El primer método consiste en establecer encabezados personalizados para cada solicitud REST   como el encabezado X-XSRF. El valor de este encabezado no importa;   simplemente la presencia debe evitar los ataques CSRF. Si llega una solicitud   en un punto final REST sin el encabezado personalizado entonces la solicitud   debe dejarse caer.

     

Las solicitudes HTTP desde un navegador web se realizan a través de formulario, imagen, iframe,   etc no pueden establecer encabezados HTTP personalizados. La única forma de crear un   La solicitud HTTP desde un navegador con un encabezado HTTP personalizado es utilizar un   Tecnología como Javascript XMLHttpRequest o Flash. Estas   Las tecnologías pueden establecer encabezados HTTP personalizados, pero tienen políticas de seguridad   incorporado para evitar que los sitios web se envíen solicitudes entre sí   a menos que la política lo permita específicamente. Esto significa que un sitio web   www.bad.com no puede enviar una solicitud a enlace con la   encabezado personalizado X-XSRFHeader a menos que utilicen una tecnología como una   XMLHttpRequest. Esa tecnología evitaría tal solicitud de   siendo hecho a menos que el dominio bank.example.com específicamente permitido   eso. Esto da como resultado un punto final REST que solo se puede llamar a través de   XMLHttpRequest (o tecnología similar).

     

Es importante tener en cuenta que este método también evita cualquier acción directa.   acceder desde un navegador web a ese punto final REST. aplicaciones web   el uso de este enfoque deberá interactuar con sus puntos finales REST   a través de XMLHttpRequest o tecnología similar.

Fuente: Pautas para implementar REST

Sin embargo, parece que la mayoría de los otros enfoques sugieren que debería generar un token y también validarlo en el servidor. ¿Es esto una ingeniería excesiva? ¿Cuándo sería seguro un enfoque de "presencia de" y cuándo también se requiere la validación del token?

    
pregunta Mads Mobæk 30.10.2012 - 10:59
fuente

4 respuestas

29

La seguridad se trata de la defensa en profundidad. Simplemente, comprobar que el valor es suficiente en este momento , pero las tecnologías y los ataques futuros pueden aprovecharse para romper su protección. La prueba de la presencia de un token logra la defensa mínima absoluta necesaria para hacer frente a los ataques actuales. Agregar el token aleatorio mejora la seguridad contra potenciales futuros vectores de ataque. El uso de un token por solicitud también ayuda a limitar el daño causado por una vulnerabilidad XSS, ya que el atacante necesita una forma de robar un token nuevo para cada solicitud que realice.

Este es el mismo razonamiento utilizado en los algoritmos criptográficos modernos, donde n rounds se considera un mínimo para la seguridad, pero 2n+1 rounds (por ejemplo) se eligen en la implementación oficial para garantizar un margen de seguridad decente.

Lectura adicional:

respondido por el Polynomial 30.10.2012 - 11:07
fuente
25

TL; DR: verificar la existencia de un encabezado no estándar como "X-Requested By" debería ser suficiente para protegerse contra los ataques CSRF sin verificar el valor del encabezado.

Los encabezados no estándar no se pueden establecer en un ataque CSRF

El sitio del framework Play lo desglosa realmente bien:

  

En pocas palabras, un atacante puede obligar a un navegador de víctimas a realizar los siguientes tipos de solicitudes:

     
  • Todas las solicitudes GET
  •   
  • solicitudes POST con cuerpos de tipo application / x-www-form-urlencoded, multipart / form-data y text / plain
  •   

Un atacante no puede:

     
  • obligue al navegador a usar otros métodos de solicitud como PUT y DELETE
  •   
  • obligue al navegador a publicar otros tipos de contenido, como application / json
  •   
  • obligue al navegador a enviar nuevas cookies, aparte de las que el servidor ya ha configurado
  •   
  • Obligue al navegador para establecer encabezados arbitrarios, aparte de los encabezados normales que el navegador agrega a las solicitudes
  •   

Esto tiene sentido si considera los vectores de ataque para CSRF:

  • solicitudes GET (por ejemplo, < img & gt ;, < iframe >), que no pueden establecer encabezados.
  • < form > enviado por un usuario, que se limita a unos pocos encabezados específicos.
  • < form > enviado por JavaScript (HTMLFormElement.submit ()), que se limita a unos pocos encabezados específicos.

JavaScript está sujeto a la política del mismo origen , por lo que solo puede agregar encabezados no estándar si es que De las siguientes condiciones se mantienen:

  • es "in-domain" (es decir, cargado desde el mismo dominio que el objetivo de la solicitud).
  • está permitido hacerlo a través de CORS .

Los ataques XSS están fuera del alcance de esta pregunta

Los encabezados no estándar se pueden configurar en un ataque XSS. El uso de un encabezado no estándar para evitar ataques CSRF no hace que un sitio sea más (o menos) vulnerable a los ataques XSS, independientemente del valor del encabezado. Tanto los encabezados no estándar como los tokens CSRF son vulnerables a los ataques XSS. Si el atacante XSS puede establecer un encabezado no estándar en una solicitud (por ejemplo, XHR en el dominio), ciertamente puede obtener acceso a un conjunto de token CSRF en una cookie o incrustado en DOM o en una variable de JavaScript.

Referencia

Hay una pregunta de SO similar aquí que es confuso pero llegó a la misma conclusión.

Algunos ejemplos de dichos encabezados no estándar en la naturaleza:

  • "X-Request-By" (mencionado por OP) reconocido por Jersey / others
  • "X-Request-With" establecido por jQuery
  • "X-XSRF-TOKEN" establecido por Angular
  • "X-CSRF-TOKEN" reconocido por el Play framework
respondido por el Chris H. 20.05.2014 - 03:42
fuente
12

EDITAR: este csrf-request-builder estaba explotando una vulnerabilidad en Flash que ahora se ha corregido. Es posible enviar solicitudes complejas con JavaScript, sin embargo, si especifica elementos adicionales del encabezado, se realizará una solicitud de preflight OPTIONS http enviado antes de la solicitud real.

He verificado que Jersy es vulnerable a CSRF y que los desarrolladores de Jersy han sido notificados. Es posible aprovechar esta vulnerabilidad utilizando Flash y la posibilidad de otras tecnologías de secuencias de comandos. Jersy es vulnerable porque el encabezado http "X-Requested-By" no está en encabezado de la lista negra de flash .

Utilicé el CSRF-Request-Builder con los siguientes argumentos para crear una solicitud de publicación:

file://var/code/CSRF-Request-Builder/csrf_payload.html#url=http://google.com&X-Requested-By=1&body={'test':1}

Nunca debe venir con su propio método de prevención de CSRF a menos que realmente entienda la explotación de CSRF. La CSRF Prevention Cheat sheet es un gran recurso.

    
respondido por el rook 30.10.2012 - 16:47
fuente
3

enlace hace un punto muy importante: la Política de Mismo Origen (SOP) se ocupa de evitar la lectura de respuestas entre dominios, no con la escritura de solicitudes.

Esto significa que, si bien es posible que pueda escribir encabezados personalizados en el futuro, es extremadamente improbable que alguna vez pueda leer la respuesta de una solicitud de varios dominios. Como tal, las mejores protecciones CSRF implican leer un valor secreto del servidor, escribirlo y hacer que el servidor valide el valor.

No necesariamente necesitas un estado del lado del servidor para lograr esto ( Double-Submit Las cookies y Patrón de token cifrado son dos ejemplos de esto) pero debe validar algunos valores secretos en el servidor.

    
respondido por el Gili 27.06.2014 - 05:45
fuente

Lea otras preguntas en las etiquetas