[Tutorial] - Protección csrf persistente

  • Autor Autor Mask7OfDragon
  • Fecha de inicio Fecha de inicio
Mask7OfDragon

Mask7OfDragon

Zeta
Verificación en dos pasos activada
Hola, en este pequeño ' Tutorial ' aprenderemos a como protegerse de Cross site forgery [CSRF] y porque es importante garantizar la proteccion contra este tipo de exploit en tu sitio.

[ Que es CSRF]

El CSRF (del inglés Cross-site request forgery o falsificación de petición en sitios cruzados) es un tipo de exploit malicioso de un sitio web en el que comando no autorizados son transmitidos por un usuario en el cual el sitio web confía. Es importante que no es lo mismo que un scam (phishing) que se basa en la clonacion del sitio.

[ Cómo protegernos ]

como aprenderemos a usar tokens, aprenderemos la primera por medio de obtención de sesión y compararla.


Organización de archivos.

- index.php
- views
-- logout.tpl.php
- app
-- class.csrf.php



Explicacion del codigo ( class.csrf.php )

En este codigo creamos una clase la cual recibirá un nombre, el nombre es usado por ejemplo para luego compararlo.
la clase como principal metodo tiene la asignacion de un metodo ( session ) a un valor.

en este sistema el csrf de la sesion nunca cambia mientras la sesion exista. ( puede ser util para sistemas donde requieras
que el indixe con la base de datos o metodos un poco ( privados ) sean accesibles, ejemplo se podria aplicar a consultar
el csrf de la session del usuario en ves de su ID.

PHP:
/**
 * archivo class.csrf.php
 */

class csrf {

	private $name;

	public function __construct($name) {

	  $this->name = $name;	

	  if (!isset($_SESSION['csrf'])) {

	  	$_SESSION['csrf'] = md5( uniqid( mt_rand(), true) );

	  } else {

	  	return $_SESSION['csrf'];
	  }

	}

	public function getProtect() {
		return $this->name;
	}

	public function setProtect($name) {
		$this->name = $name;
	}

}

Explicacion del codigo ( logout.tpl.php )

Basicamente, en este ejemplo simulo si un usuario quiere cerrar sesión. primero pasa por la validacion del csrf creado anteriormente
validamos si el get ( metodo ) es igual al de la sesion, si es igual ejecutamos nuestro codigo, si no simplemente podemos enviar una
advertencia al sistema o bloquear al usuario.

PHP:
/**
 * archivo logout.tpl.php
 */

require '/app/class.csrf.php';

if ( isset( $_GET['csrf'] ) && isset( $_SESSION['csrf'] ) && $_GET['csrf'] == $_SESSION['csrf'] ) {

	/**
         * Tu codigo.
         */

} else {

	/**
         * Tu codigo.
         */

}

Explicacion del codigo ( index.php )

No hay mucho que explicar. simplemente imprimimos el valor de csrf ( no recomiendo nunca imprimirlo en el ejemplo se da con ( get ) pero es recomendable hacerlo por ( post ) para mayor seguridad.

$_csrf se define creando una nueva instancia de csrf ( clase de csrf ) y pasando como valor un ( nombre ) en este caso. recuerda que es persistente asi que no hay problemas, solo definelo globalmente y no en cada archivo. ( ejemplo en tu archivo config.php )


PHP:
/**
 * archivo index.php
 */

$_csrf = new csrf('NombreDelUsuario');

echo $_SESSION['csrf'];

// para usarlo en logout.tpl.php tocaria llamarlo asi /views/logout.tpl.php?csrf=(tu variable $_SESSION['csrf'] )

Puntos a tener en cuenta

este pequeño sistema no es util, si el usuario puede conseguir el valor de csrf. por eso recomiendo re nombrar la variables a otro nombre, asignarlo al momento de crear la sesion o al entrar en la pagina.

en este ejemplo se ha usado para demostrar un funcionamiento bueno en un sitio donde el usuario requiere iniciar sesion para poder interactuar en este caso seria bueno agregar la sentencia en cada ( sentencias ) que pueda ejecutar el usuario, ejemplo cerrar sesion, editar el perfil, enviar mensaje entre mucho mas.

tambien podrias crear ya como ejercicio una clase donde valides todo y no tener que hacer todo el codigo en cada archivo
solo invocarlo como $_protegiendo = new protegiendo($metodo, $variable, $campo); y llamarlo en cada accion que el usuario pueda hacer.
 
Atrás
Arriba