Ir al contenido principal

AJAX y CSRF en Laravel

 ¿Las llamadas AJAX están en alcance de ciertos tipos de protección como por ejemplo contra CSRF?


Sí, lo están. Las llamadas AJAX (tanto las "simples" con GET y POST como las "complejas" con PUT, DELETE, etc.) están completamente dentro del alcance de la protección contra CSRF (Cross-Site Request Forgery).

De hecho, sin las protecciones adecuadas, las llamadas AJAX pueden ser un vector muy efectivo para ataques CSRF.

¿Por qué las llamadas AJAX son vulnerables a CSRF?

El ataque CSRF se basa en la forma en que los navegadores web manejan las cookies:

  1. El navegador envía automáticamente las cookies: Cuando un usuario está logueado en un sitio (banco.com) y tiene una sesión activa (con cookies de sesión guardadas en su navegador), si ese mismo navegador hace una solicitud a banco.com (ya sea por una acción directa del usuario, un formulario HTML o una llamada AJAX), el navegador siempre enviará automáticamente las cookies de sesión válidas para banco.com junto con la solicitud.

  2. El servidor confía en las cookies: El servidor de banco.com recibe la solicitud, ve las cookies de sesión válidas y asume que la solicitud proviene de un usuario autenticado y legítimo, por lo que procede a ejecutar la acción.

Aquí es donde entra AJAX: un atacante puede engañar al navegador de un usuario logueado para que ejecute JavaScript en una página maliciosa (sitio-malicioso.com). Este JavaScript puede construir y enviar una solicitud AJAX a banco.com. Como el navegador ya está logueado en banco.com, automáticamente adjuntará las cookies de sesión, y la solicitud parecerá legítima para el servidor de banco.com.

¿Cómo se protegen las llamadas AJAX contra CSRF?

La protección principal contra CSRF para llamadas AJAX es la misma que para los formularios HTML tradicionales: los tokens CSRF.

Así es como funciona en la práctica en frameworks como Laravel:

  1. El servidor genera un token CSRF: Cuando Laravel renderiza una vista (tu página HTML), genera un token CSRF único por sesión y lo incrusta en la página. Comúnmente, lo encontrarás en una meta etiqueta (<meta name="csrf-token" content="...">) o en un campo oculto de un formulario.

  2. JavaScript recupera el token: Tu código JavaScript (usando librerías como Axios, jQuery AJAX, o la API fetch) debe ser configurado para leer este token de la meta etiqueta o del DOM.

  3. JavaScript incluye el token en la solicitud AJAX: Antes de enviar la solicitud AJAX, tu JavaScript añade este token al request. La forma más común es enviarlo en un encabezado HTTP personalizado (por ejemplo, X-CSRF-TOKEN).

    • Ejemplo con Axios (por defecto en Laravel): Si usas Axios en un proyecto Laravel, ya viene configurado para leer la meta etiqueta csrf-token y enviarlo automáticamente en el encabezado X-XSRF-TOKEN (Laravel también busca X-XSRF-TOKEN además de X-CSRF-TOKEN).

  4. El servidor verifica el token: Cuando la solicitud AJAX llega al servidor, el middleware de CSRF de Laravel (el mismo que protege tus formularios HTML) intercepta la petición. Compara el token recibido en el encabezado (o en el cuerpo de la solicitud) con el token que tiene en la sesión del usuario.

  5. Decisión del servidor:

    • Si los tokens coinciden, la solicitud se considera legítima y se procesa.

    • Si los tokens no coinciden, la solicitud se considera un ataque CSRF y se bloquea (normalmente con un error HTTP 419 Page Expired o 403 Forbidden).

Por qué el token CSRF es efectivo contra AJAX CSRF:

El atacante que opera desde sitio-malicioso.com no puede:

  • Leer la cookie del token CSRF: La Política del Mismo Origen (SOP) lo impide.

  • Leer el contenido de la página HTML de banco.com: La SOP lo impide, por lo que no puede extraer el token de la meta etiqueta.

  • Añadir el token al encabezado o cuerpo de su solicitud AJAX forjada: Como no puede leerlo, no puede incluir el token válido.

Por lo tanto, cualquier solicitud AJAX forjada que intente enviar el atacante desde sitio-malicioso.com llegará sin el token CSRF válido, y tu servidor la rechazará.

En resumen:

Sí, las llamadas AJAX son vulnerables a CSRF. La protección se implementa eficazmente mediante el uso de tokens CSRF, que tu JavaScript debe incluir en las solicitudes AJAX (típicamente en un encabezado HTTP) para que el servidor pueda verificarlas. Esto asegura que solo las solicitudes iniciadas por tu propia aplicación (donde el token es conocido) sean procesadas.


Comentarios

Entradas populares de este blog

Crear proyecto de frontend con Vite, React, Tailwind, Typescript y JSX

 ¿Cómo se crea un proyecto exclusivo de frontend con Vite, React, Tailwind, Typescript y JSX? ¡Absolutamente! Entiendo que quieres la guía completa para pasar de cero a tener un proyecto de frontend moderno, vacío y listo para ser llenado con tu código. A continuación, te proporciono un archivo de guía detallada que incluye todos los comandos necesarios para inicializar el proyecto, configurar Tailwind CSS, y los pasos clave para empezar a "poblarlo". Voy a generar un documento Markdown con la guía paso a paso, incluyendo los comandos de terminal y las modificaciones esenciales a los archivos de configuración. Guía: Creación de un Proyecto Frontend Puro (Vite, React, TypeScript, Tailwind) Este documento detalla el proceso para inicializar un proyecto de frontend vacío y optimizado, utilizando Vite como empaquetador, React como librería, TypeScript para tipado y Tailwind CSS para estilizado. 1. Inicialización del Proyecto con Vite Vite es la herramienta más rápida para emp...

Tokens V2

Tokens: Programme to discover tokens, where there are not. Now available at  https://puszcza.gnu.org.ua/projects/tokens/ This is Version 2, for  version 1, go here . Synopsis: use TokensV2; sub printFile; my @FORMAT = ( ['<Message Date=".*?" Time=".*?" DateTime=".*?" SessionID=".*?"><From>(?:<User FriendlyName=".*?"/>)+</From><To>(?:<User FriendlyName=".*?"/>)+</To><Text(?: Style=".*?")?>.*?</Text></Message>',   sub {     my $fh = $_[1];     my ($d, $t, $f, $s, $T) = $_[0] =~ m|<Message Date="(.*?)" Time="(.*?)" DateTime=".*?" SessionID=".*?">(<From>(?:<User FriendlyName=".*?"/>)+</From>)<To>(?:<User FriendlyName=".*?"/>)+</To><Text(?: Style="(.*?)")?>(.*?)</Text></Message>|;     my $F = join '<br />', ...

Perl Net::LDAP::SimpleServer

Adaptaciones sobre el módulo LDAP Server para Windows (Strawberry Perl) Lista de adaptaciones (continúa más abajo): - Relajación de condiciones de bind:     - Cuenta principal (principal account)     - Validación de contraseñas Ubicación del archivo: %Strawberry_Perl%\site\lib\net\ldap\SimpleServer\ProtocolHandler.pm CPAN: http://search.cpan.org/~russoz/Net-LDAP-SimpleServer-0.0.17/lib/Net/LDAP/SimpleServer.pm Código: package Net::LDAP::SimpleServer::ProtocolHandler; use strict; use warnings; # ABSTRACT: LDAP protocol handler used with Net::LDAP::SimpleServer our $VERSION = '0.0.17';    # VERSION use Net::LDAP::Server; use base 'Net::LDAP::Server'; use fields qw(store root_dn root_pw allow_anon); use Carp; use Net::LDAP::LDIF; use Net::LDAP::Util qw{canonical_dn}; use Net::LDAP::FilterMatch; use Net::LDAP::Constant (     qw/LDAP_SUCCESS LDAP_AUTH_UNKNOWN LDAP_INVALID_CREDENTIALS/,   ...