Protegerse contra CSRF cuando se envía un formulario a través de una llamada AJAX

6

Estoy utilizando tokens anti-CSRF en todos mis formularios para evitar ataques CSRF. Además, los tokens se guardan en la variable $ _COOKIE para validar el valor que obtengo del formulario. Estoy restableciendo el token cada vez que se carga un formulario.

Pero hay algunos formularios que usan $ .post, es decir, AJAX para enviar y obtener una respuesta JSON.

La variable $ _COOKIE no se establece debido a que se está utilizando AJAX.

¿Hay alguna solución o estoy haciendo algo mal?

EDITAR: Agregar ejemplo de código del lado del cliente y del servidor

lado del cliente:

<?php
$tokenVal = md5(uniqid(mt_rand(), true));
setcookie ("token", $tokenVal);
?>
<form action="target.php" method="post" name="abc">
<input type="text" name="city" id="city" value="abc" size="25" maxlength="10">
<input type="hidden" name="csrf" value="<?php echo $tokenVal; ?>">
<a class="cssButton buttonColor right" id="billToSubmit">Save</a>
</form>

lado del servidor:

if($_POST['csrf'] == $_COOKIE['token']) {
//process further
} else {
die("Invalid form source")
}

El formulario se envía usando $ .post. El problema al que me enfrento es que $ _POST ['csrf'] nunca es igual a $ _COOKIE ['token']!

    
pregunta Gaurav Sharma 10.09.2012 - 22:59
fuente

4 respuestas

2

Suponiendo que el token CSRF está disponible para JavaScript, puede utilizar setRequestHeader para adjunte el token de solicitud manualmente y modifique su servidor para buscar el token de solicitud en el encabezado de la cookie, o para las solicitudes que deberían estar disponibles a través de XHR en el encabezado que proporcione.

    
respondido por el Mike Samuel 11.09.2012 - 01:15
fuente
1

La mayoría de los marcos de Javascript agregan un encabezado específico cuando POST ing solicitudes, como X-Requested-With: AJAX . En teoría, en el backend puede verificar la existencia de este encabezado para asegurarse de que su formulario se envió a través de AJAX (un atacante no debería poder hacer que un tercero agregue un encabezado personalizado al envío del formulario). Dado que las solicitudes de AJAX solo pueden provenir del mismo dominio, debe estar a salvo de los ataques CSRF.

Pero se ha descubierto que en presencia de algunas combinaciones de complementos de navegador, es realmente posible para un atacante crear una solicitud con encabezados personalizados. Esto hace que el enfoque anterior no sea tan bueno. Hoy en día, la protección preferida es pasar el token CSRF al cliente incluso para envíos AJAX. Por ejemplo, todavía puedes agregarlo a un campo oculto y luego leerlo con javascript.

EDIT : con respecto a la variable $_COOKIE$ que no se establece en las solicitudes de AJAX, no entiendo su punto. En realidad, puede establecer cookies en las solicitudes de AJAX, e incluso se conservarán las cookies normales, siempre que no sean solo de http.

    
respondido por el Andrea 11.09.2012 - 09:09
fuente
0

Esta es una forma válida de protección CSRF porque el atacante no sabrá el valor de la cookie allí para que el atacante no tenga un valor válido para la variable de publicación de token. Este método no requiere un estado por usuario que sea un beneficio.

El CSRF Prevention Cheat Sheet es un buen recurso.

    
respondido por el rook 11.09.2012 - 00:02
fuente
-1

Si está utilizando cookies para almacenar (y recuperar) el token CSRF, Eso realmente no mitiga la vulnerabilidad CSRF . Corrección: Como se aclara en los comentarios, esta línea no es cierta para la forma en que Gaurav utiliza los tokens CSRF.

En lugar de hacer tu propio esquema de prevención CSRF, ¿por qué no usar algo como PHP CSRF Guard

    
respondido por el CodeExpress 10.09.2012 - 23:27
fuente

Lea otras preguntas en las etiquetas