CSRF : CROSS SITE REQUEST FORGERY
Traducido al castellano – Falsificacion de peticion en sitios cruzados , este tipo de ataques se producen cuando el atacante provoca que el usuario ejecute una accion de forma no intencionada en una aplicación en la que habia iniciado sesión.
Ejemplo : Cuando un usuario se logea en una pagina y a continuacion hace click en un enlace que a simple vista parece normal pero en realidad es un enlace malicioso modificado por el atacante, para actulizar los datos del usuario normal por el del atacante y asi cambiar la contraseña de la cuenta mediante email.
Cualquier accion que pueda realizar el usuario cuadno está logeado en un sitio web la puede realizar también el atacante.
¿COMO EVITAR ESTE TIPO DE ATAQUES Y HACER
NUESTRA WEB SEGURA?
A continuacion vamos a seguir unos sencillos pasos para comprender como podemos implementar seguridad en nuestras paginas y asi evitar estos ataques.
Crearemos un pequeña web de productos con un login.
Empecemos Creando un proyecto MVC con Visual Estudio y le damos un nombre
Una vez creado el proyecto seguimos creando la estructura de la web :
- Creamos el controlador para el login y los productos.
- Crearemos varias vistas : Formulario , Pagina de productos , Resultado de la compra
Controlador : Le damos el nombre que queramos en mi caso lo he llamado CSRF
Lo modificamos y añadimos un ActionResult llamado Login para la validacion del usuario y tambien creamos otro ActionResult Login que sera el metodo post en el que verificaremos al usuario que se esta logeando.
El codigo para la validacion del usuario es el siguiente :
//POST: Login
//Este action result verificaremos al usuario y si tiene permiso le dejamos acceder
//y si es asi crearemos una SESSION para el.
[HttpPost]
public ActionResult Login(String usuario, String pass)
{
usuario = usuario.ToLower();
//comprobaremos si el nombre de usuario y la contraseña son correctas
if (usuario == «cliente» && pass == «cliente»)
{
//si son correctas creamos la session del usuario
Session[«CLIENTE»] = usuario;
return RedirectToAction(«Productos»);
}
else
{
//si el usuario no existe le mostramos un mensaje y la session no se crea
ViewBag.Mensaje = «Usuario – Contraseña Incorrectos»;
return View();
}
}
Creamos un ActionResult Productos donde comprobaremos si el usuario esta logeado y le permitiremos ver la pagina productos si no es asi le mandaremos a la vista login para que inicie session y asi acceder a la pagina de productos:
El codigo para verificar que el usuario esta logeado y asi permitirle el acceso a la vista productos es el siguiente :
//GET: Productos
public ActionResult Productos()
{
//comprobamos si el usuario a iniciado session
if (Session[«CLIENTE»] == null)
{
//si no ha iniciado le mandamos a la pagina del Login
return RedirectToAction(«Login»);
}
else
{
//si esta validado le dejamos entrar en la pagina de productos
return View();
}
}
Creamos otro ActionResult que seria el post de los productos en este ActionResult almacenaremos los productos elegidos por el usuario y tambien le enviaremos a la vista de compra.
El codigo para almacenar los productos es el siguiente :
[HttpPost]
public ActionResult Productos(String[] producto)
{
//almacenamos los productos elegidos por el usuario en una variable temporal
TempData[«PRODUCTOS»] = producto;
//mandamos al usuario a la pagina donde se vera el resultado de su compra
return RedirectToAction(«Compra»);
}
Por ultimo creamos el ActionResult para la vista de compra donde mostraremos los articulos comprados :
Ya tenemos la estrutura del controlador ahora seguimos creando la vista de cada ActionResult :
- Login
- Productos
- Compra
Localizamos la carpeta Views y en la carpeta que nos a creado el controlador creamos la primera vista Login , recuerda que la vista se tiene que llamar igual que el ActionResult Login, una vez creada la vista login escribimos el siguiente codigo para mostrar un formulario de acceso
El codigo del formulario es el siguiente :
<form method=»post»>
<div>
<label for=»usuario»>Usuario :</label>
<input type=»text» id=»usuario» name=»usuario» class=»form-control» />
</div>
<br />
<div>
<label for=»pass»>Contraseña :</label>
<input type=»password» id=»pass» name=»pass» class=»form-control» />
</div>
<div>
<button type=»submit» class=»btn-success»>Iniciar Sesión!</button>
</div>
</form>
Seguimos con la segunda vista que es la de Productos igual creamos un formulario con un par de productos que elegira el usuario :
El codigo del formulario de los productos es el siguiente :
<form method=»post»>
<div>
<input type=»checkbox» name=»producto» class=»form-control» style=»float:left; width:15px;»/>
<img src=»~/images/m8.png» height=»200″ width=»200″ />
<label>Bmw M8</label>
</div>
<hr />
<div>
<input type=»checkbox» name=»producto» class=»form-control» style=»float:left; width:15px;»/>
<img src=»~/images/m2.png» height=»200″ width=»200″ />
<label>Bmw M2</label>
</div>
<hr />
<div>
<input type=»checkbox» name=»producto» class=»form-control» style=»float:left; width:15px;»/>
<img src=»~/images/c2.png» height=»200″ width=»200″ />
<label>Cintroen 2Cv</label>
</div>
<br />
<button type=»submit» class=»btn-success»>Comprar</button>
</form>
Seguimos con la ultima vista que es la de compra , realizamos un if para mostrar los productos seleccionados y un ActionLink para volver a la pagina de productos
El codigo de la vista compra es el siguiente :
@model String[]
@{
ViewBag.Title = «Compra»;
}
<h2>Compra</h2>
<h2>Muchas Gracias Por la Compra!</h2>
<p>Productos Comprados :</p>
@if (Model != null)
{
<ul>
@foreach (String producto in Model)
{
<li>@producto</li>
}
</ul>
}
else
{
<h2 style=»color:red»> No hay Productos!</h2>
}
@Html.ActionLink(«Volver a los Productos», «Productos», «CSRF»)
Ya tenemos la primera parte, una web sencilla con un login y productos ahora crearemos la segunda parte que es la del atacante crearemos un nuevo proyecto en la misma solucion y le damos el nombre que queramos yo lo llamare Ataque.
Si nos fijamos en el explorador de soluciones vemos el nuevo proyecto añadido que es Ataque y el otro que es CSRF de la primera parte.
Ahora empezaremos a crear una pagina “cebo” que usaremos para engañar al usuario.
Esta pagina estara formada por un enlace malicioso que al pulsarlo compraremos los 3 articulos de la tienda sin que el usuario se haya dado cuenta y nos aparecera la vista de compra sin haber realizado ninguna compra.
Nos fijamos en el action del formulario lo estamos redirigiendo a …/CSRF/Productos
con los input ocultos.
Ya tenemos todo ahora ejecutamos las dos aplicaciones y observamos lo que ocurre:
Tenemos las dos aplicaciones ejecutadas, nos logeamos y accedemos a los productos :
Nos fijamos en la barra de direciones de las dos apliaciones cuando el usuario pulsa en el boton Gratis de la pagina realizada por el atacante,esta por detras compra los productos y lo redirige a la vista de compras.
Para evitar esto realizamos las siguientes modificaciones en la aplicación del usuario
Lo primero que tenemos realizar es usar la sintaxis Razor en el formulario de productos y usar una etiqueta llamada AntiForgeryToken que nos genera un token que evita el acceso de otros usuarios desde paginas externas a la nuestra.
El codigo modificado es el siguiente :
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div>
<input value=»m8″ type=»checkbox» name=»producto» class=»form-control» style=»float:left; width:15px;» />
<img src=»~/images/m8.png» height=»200″ width=»200″ />
<label>Bmw M8</label>
</div>
<hr />
<div>
<input value=»m2″ type=»checkbox» name=»producto» class=»form-control» style=»float:left; width:15px;» />
<img src=»~/images/m2.png» height=»200″ width=»200″ />
<label>Bmw M2</label>
</div>
<hr />
<div>
<input value=»2cv» type=»checkbox» name=»producto» class=»form-control» style=»float:left; width:15px;» />
<img src=»~/images/c2.png» height=»200″ width=»200″ />
<label>Cintroen 2Cv</label>
</div>
<br />
<button type=»submit» class=»btn-success»>Comprar</button>
}
Ahora en nuestro controlador añadimos la decoracion [ValidateAntiForgeryToken] en el ActionResult de los Productos.
Realizado estos pasos repetimos el proceso anterior, ejecutamos las dos apliaciones y comprobamos que la decoracion en el ActionResult de productos funciona.
Pulsamos en el bonton Gratis y observamos el resultado :
Como vemos nuestra aplicación ya es segura y la decoracion [ValidateAntiForgeryToken] funciona evitando el acceso de paginas externas a la nuestra.
Aqui termina este post , espero que haya sido de utilidad para proteger nuestras webs.
Autor: Jonathan Benitez Villafuerte
Curso : Microsoft MCSA Applications + Microsoft MCSD App Builder + Xamarin
Centro: Tajamar
Año Academico: 2019-2020
Codigo en Github: https://github.com/Colosus43/Cross-site-request-forgery