2012-02-01 44 views
25

Así que tengo un método POST .ajax() básico para un archivo PHP.¿Necesito un token CSRF para jQuery .ajax()?

¿Qué medidas de seguridad necesito?

Algunas publicaciones mencionaron el uso de un campo de entrada MD5 oculto que usted envía a través de AJAX y verifica en el archivo PHP. ¿Es este un método suficientemente bueno?

Respuesta

34

El riesgo de CSRF es que un sitio externo podría enviar datos al suyo y el navegador de los usuarios enviará automáticamente la cookie de autenticación junto con él.

Lo que necesita es una forma para la acción de recepción (que su método $.ajax() está enviando datos POST) para poder verificar que la solicitud proviene de otra página en su sitio, en lugar de un sitio externo.

Hay un par de formas de hacerlo, pero la forma recomendada es agregar un token a la solicitud que puede verificar y que los hackers no pueden acceder.

En su forma más simple:

  • El registro de crear una cadena aleatoria larga token y guardarlo contra el usuario.
  • Agregue un parámetro a la solicitud $.ajax() que incluye el token.
  • A petición, compruebe que el token coincide con el que ha guardado para el usuario.
  • Si el token no coincide, tiene un truco CSRF.

El hacker no puede acceder a su base de datos y no puede leer la página que ha enviado (a menos que ataque XSS, pero ese es otro problema) por lo que no puede simbólico.

Todo lo que importa con el token es que se puede predecir (y validar) y que el hacker no puede.

Por esta razón, es más fácil generar algo largo y aleatorio y almacenarlo en la base de datos, pero podría crear algo cifrado en su lugar. Sin embargo, no solo usaría el nombre de usuario MD5: si los atacantes de CSRF descubren cómo generar tus tokens, serás pirateado.

Otra forma es almacenar el token en una cookie (en lugar de en su base de datos), ya que los atacantes no pueden leer ni cambiar sus cookies, solo causan que se vuelvan a enviar. Entonces usted es el token en los datos HTTP POST coincide con el token en la cookie.

Puede hacer que estos sean mucho más sofisticados, por ejemplo, un token que cambia cada vez que se usa con éxito (evitando volver a enviar) o un token específico para el usuario y la acción, pero ese es el patrón básico.

+6

¿Cómo puede un usuario publicar una solicitud AJAX desde otro sitio web aunque la [Política de mismo origen] (https://en.wikipedia.org/wiki/Same-origin_policy) impide dicho comportamiento? – Songo

+3

@Songo no todos los navegadores admiten eso, desafortunadamente. Muchos proxies sacan encabezados y también lo rompen. Por último, puede realizar una POST desde fuera del origen, por lo que aunque tenga la intención de utilizar AJAX, eso no significa que un atacante lo haga. Básicamente, debe tener una política de origen idéntico, pero como depende de navegadores de buen comportamiento, no debe confiar en ello. El uso de un token CSRF le brinda algo que puede verificar incluso si se evita el mismo origen. – Keith

+0

@Songo, incluso con la última versión de Chrome, aún puede hacer solicitudes GET (es decir, '' '' tag en una página web) y funcionará. @Keith No confío en una cookie ya que el navegador envía automáticamente la cookie a la página web para cada solicitud. Si el atacante usa un iFrame o un formulario enviado, la cookie se enviará automáticamente, creo. – arleslie

2

En cuanto a la solicitud de falsificación, no importa cómo el cliente envía la solicitud, importa cómo se recibió. Se aplican las mismas reglas de CSRF para una publicación de Ajax que cualquier otro tipo de publicación.

Recomiendo leer el CSRF prevention cheat sheet. El uso de un token secreto por usuario es la forma más común de protección.

+2

bastante común es también símbolo de una sola vez por solicitud, adquirida a usuarios concretos y discapacitados después del primer uso. – Tadeck

+2

@Tadeck Este enfoque es más útil para evitar envíos dobles que CSRF. – rook

+2

Como se indica en [la fuente a la que se hace referencia] (https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet), los tokens de un solo uso son una seguridad muy sólida utilizada en las funciones de alto riesgo. Esto es algo opuesto a ser "más útil para evitar presentaciones dobles que CSRF_", es una forma más estricta de proteger su aplicación contra CSRF. – Tadeck

0

No se necesita ningún token, pero aún debe proteger las funciones que cambian de estado en contra de CSRF.

Una forma simple de hacerlo es agregar un encabezado que se envía con la solicitud AJAX. No se necesita ningún token aleatorio.

Esto funciona porque:

  • formularios HTML no pueden tener encabezados personalizados añadidos a ellos por un atacante.
  • Los encabezados personalizados no se pueden pasar entre dominios sin CORS habilitado.

Por supuesto, el código del lado del servidor debe garantizar que el encabezado esté presente antes de ejecutar su acción.

Más información: What's the point of the X-Requested-With header?