Foro de elhacker.net

Programación => PHP => Mensaje iniciado por: Leguim en 15 Octubre 2019, 00:29 am



Título: [Problema]: Sistema anti ataques (CSRF)
Publicado por: Leguim en 15 Octubre 2019, 00:29 am
Buenas noches,
estaba haciendo el siguiente sistema que la idea sería evitar los ataques CSRF en mi aplicación web...

Código
  1. $Token_CSRF = Create_Code();
  2. // La función "Create_Code()" lo que hace es crear un token de 22 caracteres entre ellas números y letras
  3.  

Luego en el formulario tengo un input de tipo hidden

Código
  1. <input type="hidden" name="token_csrf" value="<?php echo($Token_CSRF); ?>">
  2.  

Luego al enviar el formulario lo que hago es comparar si $_POST['token_csrf'] es igual a $Token_CSRF

Código
  1. if($_POST['token_csrf'] == $Token_CSRF)
  2. {
  3.     echo "Función ejecutada correctamente";
  4. }
  5. else
  6. {
  7.      echo "Un posible ataque CSRF fue detectado, vuelva a intentarlo.";
  8. }
  9.  

El problema es que el valor $Token_CSRF y el $_POST nunca van a ser iguales ya que al enviar el formulario no entiendo por qué razón se cambia o se "recrea" el valor de la variable $Token_CSRF ¿Como podría hacer algo para solucionar esto?


Título: Re: [Problema]: Sistema anti ataques (CSRF)
Publicado por: MinusFour en 15 Octubre 2019, 01:22 am
Tienes que guardar el token del lado del servidor, lo puedes poner en una sesión por ejemplo. Ese es el valor que tienes que comparar contra el valor que recibes por POST.


Título: Re: [Problema]: Sistema anti ataques (CSRF)
Publicado por: Leguim en 15 Octubre 2019, 01:30 am
Tienes que guardar el token del lado del servidor, lo puedes poner en una sesión por ejemplo. Ese es el valor que tienes que comparar contra el valor que recibes por POST.

Si si, estoy guardando el token del lado del servidor pero no entiendo por qué sucede eso... si hasta donde yo lo veo como yo hice debería de funcionar de 100 pero siempre puede pasar que algo se me escape...

Intente con las $_SESSION pero es lo mismo, al enviar dicho formulario como que la variable que guarda el dato de la función "Create_Code" es como que se dispara otra vez, y de esta forma genera un nuevo token sin que yo se lo pida..


Título: Re: [Problema]: Sistema anti ataques (CSRF)
Publicado por: @XSStringManolo en 15 Octubre 2019, 02:30 am
Pasa el código que tengas, igual estás metiendo la llamada a la función en un if en vez de la varible que contiene el valor de retorno? Si utilizas la llamada como si fuese el valor del return en el if pasaría eso de que se te ejecuta 2 veces.


Título: Re: [Problema]: Sistema anti ataques (CSRF)
Publicado por: #!drvy en 15 Octubre 2019, 09:46 am
Igual estás ejecutando la función antes de la comprobación del token ende se genera un nuevo token antes de validar el antiguo. Si es el caso, yo  lo que suelo hacer es guardar el valor antiguo y el nuevo. Usas el antiguo para comparar y el nuevo para insertar en campos.

Un ejemplo así sin pensarlo mucho:

Código
  1. function createToken($name = 'token')
  2. {
  3.    $new_name = 'csrf_'.$name;
  4.    $old_name = 'csrf_old_'.$name;
  5.  
  6.    if (!empty($_SESSION[$new_name])) {
  7.        $_SESSION[$old_name] = $_SESSION[$new_name];
  8.    }
  9.  
  10.    $rand = bin2hex(random_bytes(32));
  11.    $_SESSION[$new_name] = $rand;
  12.    return $rand;
  13. }
  14.  
  15.  
  16. function validateToken($name = 'token', $value = null)
  17. {
  18.    $old_name = 'csrf_old_'.$name;
  19.  
  20.    if (!empty($_SESSION[$old_name]) && $_SESSION[$old_name] === $value) {
  21.        return true;
  22.    }
  23.  
  24.    return false;
  25. }


Código
  1. <?php
  2. $csrf_token = createToken('patata');
  3.  
  4.  
  5. if (isset($_POST['csrf_token']) && validateToken('patata', $_POST['csrf_token'])) {
  6.    echo 'token valido';
  7. }
  8.  
  9. ?>
  10.  
  11.  
  12. <form method='POST'>
  13.    <input name='csrf_token' type='hidden' value='<?=$csrf_token?>'>
  14.    <button type='submit'>Enviar</button>
  15. </form>



PD: Comprueba siempre los strings con === (3 iguales) en vez de 2.
https://stackoverflow.com/questions/4732706/whats-the-difference-between-equal-and-identical-comparison-operators-in-php

PD2: echo NO es una función. No uses paréntesis () si no vas a hacer comprobaciones.
https://www.php.net/manual/es/function.echo.php
Nota: Puesto que esto es una construcción del lenguaje y no una función, no puede ser llamada usando funciones variables.


Saludos


Título: Re: [Problema]: Sistema anti ataques (CSRF)
Publicado por: Leguim en 16 Octubre 2019, 23:01 pm
Me dio unos problemas al principio pero ya todo funciona muy bien, me gusto mucho la lógica de tu idea!

Gracias!