Comprendiendo CSRF en profundidad
Proporciona una exploración en profundidad de los ataques de falsificación de solicitudes entre sitios (CSRF), explicando su mecánica, demostrando ejemplos y detallando varios métodos de prevención para mejorar la seguridad de las aplicaciones web.
Cuando trabajamos en el desarrollo web, especialmente con cookies, a menudo escuchamos frases como "esta configuración ayuda a prevenir CSRF". Sin embargo, muchas personas solo tienen una idea vaga de qué significa realmente "CSRF".
Hoy, profundizaremos en CSRF (falsificación de solicitudes entre sitios), una falla común en la seguridad web. Esto nos ayudará a manejar los problemas relacionados con CSRF de manera más efectiva.
¿Qué es CSRF?
CSRF (falsificación de solicitudes entre sitios) es un tipo de ataque web donde los atacantes engañan a usuarios autenticados para que realicen acciones no intencionadas. En términos simples, es "hackers pretendiendo ser usuarios para llevar a cabo acciones no autorizadas".
Cómo funciona CSRF
Para entender CSRF, necesitamos comprender algunos conceptos clave:
Política de mismo origen del navegador
La política de mismo origen es una característica de seguridad en los navegadores que limita cómo un documento o script de un origen puede interactuar con recursos de otro origen.
Un origen consiste en un protocolo (como HTTP o HTTPS), nombre de dominio y número de puerto. Por ejemplo, https://example.com:443
es un origen, mientras que https://demo.com:80
es otro.
La política de mismo origen restringe el acceso a datos entre páginas de diferentes orígenes, lo que significa:
- JavaScript de un origen no puede leer el DOM de otro origen
- JavaScript de un origen no puede leer las cookies, IndexedDB o localStorage de otro origen
- JavaScript de un origen no puede enviar solicitudes AJAX a otro origen (a menos que use CORS)
Sin embargo, para mantener la apertura e interoperabilidad de la Web (como cargar recursos de CDNs o enviar solicitudes a APIs de terceros para registros), la política de mismo origen no restringe las solicitudes de red entre orígenes:
- Las páginas pueden enviar solicitudes GET o POST a cualquier origen (como cargar imágenes o enviar formularios)
- Los recursos de cualquier origen pueden ser incluidos (como etiquetas
<script>
,<img>
,<link>
,<iframe>
)
Mecanismo automático de envío de cookies
El mecanismo automático de envío de cookies es una característica importante de los navegadores. Cuando un navegador envía una solicitud a un dominio, automáticamente adjunta todas las cookies para ese dominio. Este proceso es automático y no requiere ningún código JavaScript o interacción del usuario.
Este mecanismo permite que los sitios web recuerden fácilmente el estado de inicio de sesión de los usuarios porque cada solicitud lleva automáticamente la información de identidad del usuario.
Negrita
Por ejemplo, cuando inicias sesión en un sitio web bancario (bank.com
) y obtienes una cookie de identidad, luego, cuando haces clic para ver tu estado de cuenta, el navegador encuentra automáticamente todas las cookies que coinciden con bank.com
y las adjunta a la solicitud de estado de cuenta. El servidor del banco puede entonces identificarte desde el backend y devolver tu información del estado de cuenta.
Pasos de un ataque CSRF
-
El usuario inicia sesión en el sitio web objetivo (como un sitio bancario) y obtiene una cookie de autenticación. Este paso utiliza el mecanismo automático de envío de cookies. Después de que el sitio bancario establece una cookie de autenticación de identidad, el navegador adjuntará automáticamente esta cookie a cada solicitud enviada a ese sitio.
-
Sin cerrar sesión, el usuario visita un sitio web malicioso. En este punto, debido a la política de mismo origen, el sitio malicioso no puede leer o modificar directamente la cookie del sitio bancario. Esto protege la información de identidad del usuario de ser robada directamente.
-
El sitio malicioso incluye una solicitud al sitio objetivo (como una operación de transferencia). Aunque la política de mismo origen restringe el acceso entre orígenes, permite solicitudes de red entre orígenes, como solicitudes iniciadas a través de etiquetas
<img>
,<form>
. Los atacantes explotan esta "falla". -
El navegador del usuario envía automáticamente esta solicitud, junto con la cookie del sitio objetivo. Este es el núcleo del ataque CSRF. Aprovecha tanto la política de mismo origen que permite solicitudes entre orígenes como el mecanismo automático de envío de cookies (incluso las solicitudes activadas por sitios maliciosos llevarán cookies que coincidan con el dominio).
-
El sitio objetivo recibe la solicitud, verifica que la cookie sea válida y ejecuta la operación. El servidor no puede saber si esta solicitud proviene de una acción legítima del usuario porque la cookie adjunta es válida.
Ejemplo de ataque CSRF
Ilustremos cómo ocurre un ataque CSRF con un ejemplo específico. Usaremos un sitio web bancario ficticio bank.com
como ejemplo.
Primero, el usuario visita https://bank.com
e inicia sesión en su cuenta.
Después del inicio de sesión exitoso, el servidor establece una cookie de autenticación, por ejemplo:
El usuario realiza una operación de transferencia en el sitio web del banco, digamos transferir $1000 a Alice. Esta operación podría enviar una solicitud como esta:
Ahora, supongamos que un atacante crea un sitio web malicioso https://evil.com
que contiene el siguiente HTML:
Cuando el usuario hace clic en el enlace https://evil.com
sin cerrar sesión de su cuenta bancaria, como ya ha iniciado sesión en bank.com
, el navegador tiene una cookie session_id
válida.
Después de que la página maliciosa se cargue, automáticamente envía el formulario oculto, enviando una solicitud de transferencia a https://bank.com/transfer
.
El navegador del usuario adjunta automáticamente la cookie de bank.com
a esta solicitud. El servidor de bank.com
recibe la solicitud, verifica que la cookie sea válida y luego ejecuta esta operación de transferencia no autorizada.
Métodos comunes para prevenir ataques CSRF
Aquí hay varios métodos de defensa contra CSRF comúnmente utilizados. Explicaremos en detalle el principio de cada método y cómo previene eficazmente los ataques CSRF:
Uso de tokens CSRF
Los tokens CSRF son uno de los métodos más comunes y efectivos para defenderse de los ataques CSRF. Así es como funciona:
- El servidor genera un token único e impredecible para cada sesión.
- Este token se incrusta en todos los formularios para operaciones sensibles.
- Cuando el usuario envía un formulario, el servidor verifica la validez del token.
Debido a que el token CSRF es un valor único vinculado a la sesión del usuario, y el atacante no puede conocer o adivinar este valor (ya que es diferente para cada sesión), incluso si el atacante engaña al usuario para que envíe una solicitud, la solicitud será rechazada por el servidor debido a la falta de un token CSRF válido.
Ejemplo de implementación:
En el servidor (usando Node.js y Express):
En JavaScript del frontend:
Comprobación del encabezado Referer
El encabezado Referer
contiene la URL de la página que inició la solicitud. Verificando el encabezado Referer
, el servidor puede determinar si la solicitud proviene de una fuente legítima.
Dado que los ataques CSRF generalmente provienen de diferentes dominios, el encabezado Referer
mostrará el nombre de dominio del atacante. Al verificar si el Referer
es el valor esperado, las solicitudes de fuentes desconocidas pueden ser bloqueadas.
Sin embargo, vale la pena señalar que este método no es completamente confiable, ya que algunos navegadores podrían no enviar el encabezado Referer, y los usuarios pueden deshabilitar el encabezado Referer a través de configuraciones del navegador o complementos.
Ejemplo de implementación:
Uso del atributo SameSite
en cookies
SameSite
es un atributo de cookie utilizado para controlar si las cookies se envían con solicitudes entre sitios. Tiene tres valores posibles:
Strict
: Las cookies solo se envían en solicitudes del mismo sitio.Lax
: Las cookies se envían en solicitudes del mismo sitio y navegación de nivel superior.None
: Las cookies se envían en todas las solicitudes entre sitios (debe usarse con el atributoSecure
).
Cuando SameSite
se establece en Strict
, puede prevenir completamente que sitios web de terceros envíen cookies, evitando así eficazmente los ataques CSRF.
Si SameSite
se establece en Lax
, protege operaciones sensibles mientras permite algunos casos comunes de uso entre sitios (como ingresar a un sitio web desde enlaces externos).
Ejemplo de implementación:
Uso de encabezados de solicitud personalizados
Para solicitudes AJAX, se pueden agregar encabezados de solicitud personalizados. Debido a las restricciones de la política de mismo origen, los atacantes no pueden establecer encabezados personalizados en solicitudes entre orígenes. El servidor puede verificar la presencia de este encabezado personalizado para verificar la legitimidad de la solicitud.
Ejemplo de implementación:
En el frontend:
En el lado del servidor:
Verificación doble de cookies
La verificación doble de cookies es una técnica efectiva de defensa contra CSRF. Su principio básico es que el servidor genera un token aleatorio, lo establece como cookie y lo incrusta en la página (generalmente como un campo de formulario oculto). Cuando el navegador envía una solicitud, automáticamente incluye la cookie, mientras que el JavaScript de la página envía el token como un parámetro de solicitud. El servidor luego verifica si el token en la cookie coincide con el token en los parámetros de la solicitud.
Aunque los atacantes pueden incluir la cookie del sitio web objetivo en solicitudes entre sitios, no pueden leer o modificar el valor de la cookie, ni pueden acceder o modificar el valor del token en la página. Al requerir que la solicitud incluya tokens tanto de la cookie como de los parámetros, asegura que la solicitud provenga de una fuente con permiso para leer la cookie, defendiendo así eficazmente contra ataques CSRF.
Uso de reautenticación para operaciones sensibles
Para operaciones particularmente sensibles (como cambiar contraseñas o realizar grandes transferencias), se puede requerir que los usuarios se reautentiquen. Esto proporciona a los usuarios un punto adicional de control de seguridad. Incluso si un usuario inicia con éxito un ataque CSRF, no podrá pasar el paso de reautenticación.
Sugerencias de implementación:
- Antes de realizar operaciones sensibles, redirigir a una página de autenticación separada.
- En esta página, requerir que el usuario ingrese su contraseña u otra información de verificación de identidad.
- Después de que la verificación pase, generar un token de un solo uso y usar este token en operaciones sensibles subsecuentes.
Resumen
A través de esta discusión en profundidad, esperamos que ahora tengas una comprensión más completa de los ataques CSRF. No solo hemos aprendido cómo funciona CSRF, sino que también hemos explorado varias medidas de defensa efectivas. Todos estos métodos pueden mejorar eficazmente la seguridad de las aplicaciones web.
Esperamos que este conocimiento te ayude a manejar mejor los problemas relacionados con CSRF en tu desarrollo diario y a construir aplicaciones web más seguras.