Este wikiHow le enseña cómo prevenir un ataque de falsificación de solicitudes entre sitios (CSRF) en una aplicación web de PHP al incluir un token aleatorio con cada solicitud o al usar un nombre aleatorio para cada campo de formulario. Un ataque de falsificación de solicitudes entre sitios (CSRF) aprovecha una vulnerabilidad de aplicación web en la que la víctima ejecuta sin querer un script en su navegador que aprovecha su sesión iniciada en un sitio en particular. Los ataques CSRF se pueden realizar a través de solicitudes GET o POST.

Parte uno de cinco:
Visión general de los métodos

Utilizaremos dos métodos para ayudar a prevenir ataques CSRF en sus solicitudes GET y POST:

  1. 1 Incluye un token aleatorio con cada solicitud. Esta es una cadena única que se genera para cada sesión. Generamos el token y luego lo incluimos en todas sus formas como una entrada oculta. El sistema luego verifica si el formulario es válido comparando el token con el almacenado en la variable de sesión del usuario. Un atacante no podrá generar una solicitud sin conocer el valor del token.
  2. 2 Usando un nombre al azar para cada campo de formulario. El valor del nombre aleatorio para cada campo se almacena en una variable de sesión. Después de que se haya enviado el formulario, el sistema genera un nuevo valor aleatorio. Para tener éxito, un atacante tendría que adivinar estos nombres de forma aleatorios.
    • Por ejemplo, una solicitud que alguna vez se veía así:
    • Ahora se verá así:

Parte dos de cinco:
Crear el archivo de clase CSRF

  1. 1 Crear csrf.class.php. Este es el archivo que contendrá todas las funciones que se usarán para evitar ataques CSRF.
     <? php clase csrf  
  2. 2 Guarda el archivo.
    • Todo el código en las Partes 2 y 3 se agregará al final de este archivo.

Parte tres de cinco:
Agregar un token aleatorio

  1. 1 Crea el get_token_id () función. Esta función recupera el ID del token de la sesión de un usuario, y si uno no se ha creado genera un token aleatorio.
     público función get_token_id()  Si(Está establecido($ _SESSION['token_id']))  regreso $ _SESSION['token_id'];  más  $ token_id = $ this->aleatorio(10); $ _SESSION['token_id'] = $ token_id; regreso $ token_id;   
  2. 2 Crea el get_token () función. Esta función recupera el valor del token o, si no se ha generado, genera un valor de token.
     público función get_token()  Si(Está establecido($ _SESSION['token_value']))  regreso $ _SESSION['token_value'];  más  $ token = picadillo('sha256', $ this->aleatorio(500)); $ _SESSION['token_value'] = $ token; regreso $ token;   
  3. 3 Crea el check_valid () función. Esta función determina si la ID del token y el valor del token son ambos válidos. Esto se hace comprobando los valores de la solicitud GET o POST con los valores almacenados en la variable SESSION del usuario.
     público función check_valid($ método)  Si($ método == 'enviar' || $ método == 'obtener')  $ post = $ _POST; $ get = $ _GET; Si(Está establecido($$ método[$ this->get_token_id()]) && ($$ método[$ this->get_token_id()] == $ this->get_token()))  regreso cierto;  más  regreso falso;   más  regreso falso;   

Parte cuatro de cinco:
Generando un nombre aleatorio para cada campo de formulario

  1. 1 Crea el form_names () función. Esta función genera nombres aleatorios para los campos de formulario.
     público función form_names($ nombres, $ regenerar)  $ valores = formación(); para cada ($ nombres como $ n)  Si($ regenerar == cierto)  desarmado($ _SESSION[$ n]);  $ s = Está establecido($ _SESSION[$ n]) ? $ _SESSION[$ n] : $ this->aleatorio(10); $ _SESSION[$ n] = $ s; $ valores[$ n] = $ s;  regreso $ valores;  
  2. 2 Crea el aleatorio función. Esta función genera una cadena aleatoria utilizando el archivo aleatorio de Linux para crear más entropía.
     privado función aleatorio($ len)  Si (function_exists('openssl_random_pseudo_bytes'))  $ byteLen = intval(($ len / 2) + 1); $ retorno = substr(bin2hex(openssl_random_pseudo_bytes($ byteLen)), 0, $ len);  elseif (@is_readable('/ dev / urandom'))  $ f=fopen('/ dev / urandom', 'r'); $ urandom=fread($ f, $ len); fclose($ f); $ retorno = ";  Si (vacío($ retorno))  para ($ i=0;$ i<$ len;++$ i)  Si (!Está establecido($ urandom))  Si ($ i%2==0)  mt_srand(hora()%2147 * 1000000 + (doble)microtime() * 1000000);  $ rand=48+mt_rand()%64;  más  $ rand=48+ord($ urandom[$ i])%64;  Si ($ rand>57) $ rand+=7; Si ($ rand>90) $ rand+=6; Si ($ rand==123) $ rand=52; Si ($ rand==124) $ rand=53; $ retorno.=chr($ rand);   regreso $ retorno;  
  3. 3 Cerrar la clase csrf soporte.
      
  4. 4Cierra el csrf.class.php archivo.

Parte cinco de cinco:
Usando el archivo de clase CSRF

  1. 1 Agregue el archivo de clase CSRF a un formulario POST. El código que se muestra aquí le muestra cómo agregar el archivo CSRF Class a un formulario POST para evitar un ataque CSRF.
     <? php session_start(); incluir 'csrf.class.php'; $ csrf = nuevo csrf(); // Generar identificador de token y válido $ token_id = $ csrf->get_token_id(); $ token_value = $ csrf->get_token($ token_id); // Generar nombres de formulario aleatorios $ form_names = $ csrf->form_names(formación('usuario', 'contraseña'), falso); Si(Está establecido($ _POST[$ form_names['usuario']], $ _POST[$ form_names['contraseña']]))  // Verifica si la identificación del token y el valor del token son válidos. Si($ csrf->check_valid('enviar'))  // Obtenga las Variables de Forma. $ usuario = $ _POST[$ form_names['usuario']]; $ contraseña = $ _POST[$ form_names['contraseña']]; // Función de formulario va aquí  // Regenerar un nuevo valor aleatorio para el formulario. $ form_names = $ csrf->form_names(formación('usuario', 'contraseña'), cierto);  ?>