[Pregunta]: Token CSRF

Iniciado por Leguim, 3 Diciembre 2019, 05:52 AM

0 Miembros y 1 Visitante están viendo este tema.

Leguim

Buenas noches,

Quería preguntarles porque yo tengo un sistema para evitar ataques CSRF en mi aplicació  web, logicamente estoy usando tokens para esto. Hasta ahora solamente los estoy usando para el envio de formularios (PHP) quería saber donde más ven necesario el uso de este "parcheado"?

#!drvy

Cualquier acción que afecte al usuario de una manera o de otra. Cerrar sessión, cambiar de estado, actualizar algún dato, hacer una petición GET importante etc..

Saludos

@XSStringManolo

Como te dice Drvy, es cualquier acción que pieda hacer algo que el usuario pieda no desear. Por ejemplo si te mando Wikipedia y no usas token, te estaría desloggeando de la cuenta. Este link podría meterlo por ejemplo en mi página web o como foto de perfíl. En el caso de ponerlo de foto de perfíl, todo el mundo que viese mi imagen, por ejemplo tú ahora; seguiría el link de la imagen automáticamente por el navegador para descargarla, lo cual haría que todos los usuarios de Elhacker que viesen cualquiera de mis posts se desloggeasen automáticamente.

Otro ejemplo sería el de que yo meditante javascript haga submit a un form de elhacker.net por ejemplo: publicarPost.php
Si no existe token ni confirmación, podría hacer autosubmit del form desde mi web. Por lo que podría ir publicando nuevos temas y respondiendo a temas desde otras cuentas.

Por eso se añade sesc=jsjsjsjsjsjsjsjsjsjsjsjsjsjsjsjsjs al link o hidden en el form y se valida en el servidor.

Deberías usar los tokens en todo lo que no sea una acción que no afecte de ninguna forma. Por ejemplo pinchar en el link de foro, o ayuda no entraña ningún riesgo.

Por temas relacionados también es recomendable evitar que se use tu web en iframes de páginas externas mandando la cabecera pertinente al navegador.

Leguim

Imagino que voy a tener que actualizar o crear 2 sistemas anti CSRF totalmente diferentes ya que como hago para hacer un token para cada pagina (mejor dicho para cada pagina que use $_GET por ejemplo o cambie de estado)

ya que la manera en como lo hago no me va a servir para esto (si para los formularios) pero no para esto... (este método no me acuerdo bien quien me lo había pasado creo que era EdePC o !Drvy) lo había mejorado un poco y quedo así:

Código (php) [Seleccionar]

function Create_Token($name)
{
$result = 'Error';

if(is_string($name))
{
$token_new = 'token_'.($name);
$token_old = 'token_old_'.($name);

if(isset($_SESSION[$token_new]))
{
if(!empty($_SESSION[$token_new]))
{
$_SESSION[$token_old] = $_SESSION[$token_new];
}
}

$_SESSION[$token_new] = Create_Code();
$result = $_SESSION[$token_new];
}

return $result;
}


la parte de verificación sería:

Código (php) [Seleccionar]

function Validate_Token($name, $value)
{
$result = false;

if(is_string($name) && is_string($value))
{
$token_old = 'token_old_'.($name);

if(isset($_SESSION[$token_old]))
{
if(!empty($_SESSION[$token_old]) && $_SESSION[$token_old] === $value)
{
$result = true;
}
}
}

    return $result;
}


En un formulario...

[Creo el token con el nombre del formulario]
[El valor del token lo mando a input de tipo hidden]
[Lo recibo  por $_POST y lo valido por el nombre del token creado anteriormente]

¿Como puedo aplicar esto a por ejemplo una pagina que reciba $_GET?

@XSStringManolo

Con el código que mandas no puedo ver como generas el token.
Lo que veo es que tu token es:
token_upload.php  ?

Si es así es inutil. El token debe ser impredecible. Si es así como lo tienes, si alguien visita mi página web y tiene session abierta en la tuya, les borro las cuentas de tu sitio automáticamente. Solo tengo que mirar como se llama la acción de borrar cuenta y agregar al form token_delete.php

Puedes usar la session directamente, o aplicarle un hash al form y a la session para comparar.

Yo personalmente uso criptografía simétrica. Genero un string random a partir de un CSPRNG, se lo aplico a datos del usuario como id, trozo de session cookie y fecha. Y se lo pongo en el form de CADA página generada. Cuando hace submit compruebo que todo esté correcto. Por algún tema tuyo se comentó una función CSPRNG segura de PHP 7+. Yo uso todo algoritmos propios.

Si usas algún framework te suelen traer funciones para ello. Si no te quieres complicar usa hmac y le pasas sha512 la página a la que haces action/submit  y la session. Con 3 o 4 líneas de código lo tienes listo.

Yo te recomiendo no hacer este tipo de acciones nunca con GET. Hay muchos ataques csrf que solo funcionan por GET, se te pueden escapar los tokens en la url con el referer si no lo haces correctamente, etc.