Protección CSRF

  • Introducción
  • Prevención de solicitudes CSRF
    • Exclusión de URIs
  • X-CSRF-Token
  • X-XSRF-Token

Introducción

Las falsificaciones de peticiones cruzadas son un tipo de exploit malicioso por el que se realizan comandos no autorizados en nombre de un usuario autenticado. Afortunadamente, Laravel hace que sea fácil proteger su aplicación de los ataques de falsificación de solicitud de sitio cruzado (CSRF).

Una explicación de la vulnerabilidad

En caso de que no esté familiarizado con las falsificaciones de solicitud de sitio cruzado, vamos a discutir un ejemplo de cómo esta vulnerabilidad puede ser explotada. Imagina que tu aplicación tiene una ruta /user/email que acepta una petición POST para cambiar la dirección de correo electrónico del usuario autenticado. Lo más probable es que esta ruta espere que un campo de entrada email contenga la dirección de correo electrónico que el usuario desea comenzar a utilizar.

Sin protección CSRF, un sitio web malicioso podría crear un formulario HTML que apunte a la ruta /user/email de su aplicación y envíe la propia dirección de correo electrónico del usuario malicioso:

<form action="https://your-application.com/user/email" method="POST"> <input type="email" value=""></form><script> document.forms.submit();</script>

Si el sitio web malicioso envía automáticamente el formulario cuando se carga la página, el usuario malicioso sólo necesita atraer a un usuario desprevenido de su aplicación para que visite su sitio web y su dirección de correo electrónico será cambiada en su aplicación.

Para evitar esta vulnerabilidad, es necesario inspeccionar cada petición entrante POST, PUT, PATCH o DELETE en busca de un valor de sesión secreto al que la aplicación maliciosa no pueda acceder.

Prevención de peticiones CSRF

Laravel genera automáticamente un «token» CSRF para cada sesión de usuario activa gestionada por la aplicación. Este token se utiliza para verificar que el usuario autentificado es la persona que realmente realiza las peticiones a la aplicación. Como este token se almacena en la sesión del usuario y cambia cada vez que se regenera la sesión, una aplicación maliciosa no puede acceder a él.

Se puede acceder al token CSRF de la sesión actual a través de la sesión de la solicitud o a través de la función helper csrf_token:

use Illuminate\Http\Request;Route::get('/token', function (Request $request) { $token = $request->session()->token(); $token = csrf_token(); // ...});

Cada vez que defina un formulario HTML en su aplicación, debe incluir un campo oculto CSRF _token en el formulario para que el middleware de protección CSRF pueda validar la solicitud. Para mayor comodidad, puedes utilizar la directiva @csrf Blade para generar el campo de entrada de token oculto:

<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>

El middleware App\Http\Middleware\VerifyCsrfToken, que está incluido en el grupo de middleware web por defecto, verificará automáticamente que el token en la entrada de la solicitud coincide con el token almacenado en la sesión. Cuando estos dos tokens coinciden, sabemos que el usuario autenticado es el que inicia la petición.

CSRF Tokens & SPAs

Si estás construyendo una SPA que utiliza Laravel como backend de la API, deberías consultar la documentación de Laravel Sanctum para obtener información sobre la autenticación con tu API y la protección contra vulnerabilidades CSRF.

Excluir URIs de la protección CSRF

A veces puede desear excluir un conjunto de URIs de la protección CSRF. Por ejemplo, si está utilizando Stripe para procesar los pagos y está utilizando su sistema de webhook, tendrá que excluir su ruta de manejador de webhook de Stripe de la protección CSRF ya que Stripe no sabrá qué token CSRF enviar a sus rutas.

Típicamente, debe colocar este tipo de rutas fuera del grupo de middleware web que el App\Providers\RouteServiceProvider aplica a todas las rutas en el archivo routes/web.php. Sin embargo, también puede excluir las rutas añadiendo sus URIs a la propiedad $except del middleware VerifyCsrfToken:

<?phpnamespace App\Http\Middleware;use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;class VerifyCsrfToken extends Middleware{ /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = ;}

{tip} Para mayor comodidad, el middleware CSRF se desactiva automáticamente para todas las rutas cuando se ejecutan pruebas.

X-CSRF-TOKEN

Además de comprobar el token CSRF como parámetro POST, el middleware App\Http\Middleware\VerifyCsrfToken también comprobará la cabecera de solicitud X-CSRF-TOKEN. Podría, por ejemplo, almacenar el token en una etiqueta HTML meta:

<meta name="csrf-token" content="{{ csrf_token() }}">

Entonces, puede instruir a una biblioteca como jQuery para que añada automáticamente el token a todas las cabeceras de solicitud. Esto proporciona una protección CSRF simple y conveniente para sus aplicaciones basadas en AJAX que utilizan tecnología JavaScript heredada:

$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta').attr('content') }});

X-XSRF-TOKEN

Laravel almacena el token CSRF actual en una cookie XSRF-TOKEN encriptada que se incluye con cada respuesta generada por el framework. Se puede utilizar el valor de la cookie para establecer la cabecera de petición X-XSRF-TOKEN.

Esta cookie se envía principalmente como una comodidad para el desarrollador ya que algunos frameworks y librerías de JavaScript, como Angular y Axios, colocan automáticamente su valor en la cabecera X-XSRF-TOKEN en las peticiones del mismo origen.

Deja un comentario