El Cross-site request forgery (CSRF) o falsificación de petición en sitios cruzados (también conocido como Session Riding) es un tipo de script malicioso de un sitio web en el que comandos no autorizados son transmitidos por un usuario en el cual el sitio web confía. Esta vulnerabilidad es conocida también por otros nombres como XSRF, enlace hostil, ataque de un click, cabalgamiento de sesión o ataque automático.
Se trata de una técnica que permite aprovechar una sesión abierta en el navegador con un sitio fiable, para que desde el código HTML de una página que estemos visitando se cree una petición que podría tener la consecuencia de enviar una petición (legítima en apariencia porque procede de un navegador en el que mantenemos una sesión válida abierta) a la aplicación web del banco para que realice una operación sin que sea en ningún momento evidente.
Actualmente la mayoría de frameworks web implementan el uso de tokens, que básicamente es uno de los mecanismos para proteger las aplicaciones y sus peticiones. Se basa en la generación y codificación de un número aleatorio (token) tras un inicio de sesión exitoso, de tal forma que en cada formulario que se le presente al usuario se incluye un campo oculto en el que se escribe este token, ya luego el servidor verificará si el token enviado es igual al generado o no y eso determinará si o no se procesará la solicitud.
Normalmente cuando trabajamos con un solo lenguaje tanto para frontend como backend, es muy fácil implementar el uso de csrf token, porque lo que hacen los frameworks es poner el token en un campo oculto del formulario y enviarlo junto con toda la petición, pero el problema llega cuando intentamos hacer peticiones vía ajax por métodos diferentes al GET (porque el método get no necesita token).
Para hacer peticiones vía ajax y enviar el token, existen diferentes maneras de hacerlo por ejemplo, serializando todo el formulario y pasándolo al parámetro data de ajax.
$.ajax({ type: 'POST', url: http://localhost/test, data: $('#formulario').serialize(), success: function(data) { // ... } }); |
Otra opción que por si no quieren enviar todos los parámetros de un formulario es crear un objeto literal y nuevamente pasarlo al parámetro data.
$.ajax({ type: 'POST', url: 'http://localhost/test', data: { token: csrf_token, param1: 'abc', param2: '123 }, success: function(data) { // ... } }); |
Otra puede ser esta, que es la que últimamente he estado implementando, básicamente lo que hago es enviar el token directamente como un parámetro en las cabeceras de la solicitud y para eso modifico el evento ajaxsend.
$('body').bind('ajaxSend', function(elm, xhr, s) { if (s.type != 'GET') { xhr.setRequestHeader('X-CSRF-TOKEN', csrf_token); } }); |
Claro que para hacerlo funcionar en el servidor es necesario también modificar alguno de los eventos del controlador base, pero eso ya depende del framework.
Happy Coding! 🙂
Pregunta los token solo se generan bajo solisitudes del cliente?
Enoc, estos tokens son generados por el servidor y enviados a los clientes, de tal manera que en cada petición que se hace, el servidor verifica si el token generado es correcto y de esa forma permitir la ejecución del recurso solicitado.
Son muy utilizados por ejemplo para prevenir la ejecución remota de formularios, el servidor espera un token y si no es enviado o no corresponde al creado, seguramente se trata de una petición de spam o algo malicioso.
Hola, se que el post ya tiene varios años publicado pero no está demás preguntar. Como se recibe ese token del lado del servidor con php, considerando que no se enviará vía get ni post, según la última forma que explicaste, que dices que es la que usas últimamente.
Gracias.
Hola Anthony, como decía en una respuesta pasada, la forma en que recibas o tomes el token, depende mucho del framework o la implementación que tengas del lado del servidor, pero básicamente el cliente está enviando en token por “Headers” y por lo tanto en el servidor con un simple getallheaders() podrías tomar ese valor .. mira esto puede ayudarte, para ser mas específico http://php.net/manual/en/function.getallheaders.php
Saludos
Hola, una consulta: El token que se genera en el servidor y es enviado al cliente, se puede enviar por la consola del browser con ajax (jquery) . Hay una manera de restringir esto?
Cuando vienes a Nicaragua?