CSRF (Cross-Site Request Forgery)

🌐 Vulnerabilidad: Cross-Site Request Forgery (CSRF)


🕵️‍♂️ ¿Qué es CSRF?

Cross-Site Request Forgery (CSRF) es una vulnerabilidad que permite a un atacante engañar a un usuario autenticado para que realice acciones no deseadas en una aplicación web en la que tiene sesión activa. Esto se logra enviando solicitudes maliciosas en nombre del usuario sin su conocimiento.


⚙️ ¿Cómo se produce?

  1. El usuario tiene sesión activa en un sitio web legítimo (por ejemplo, un banco).

  2. El atacante envía una solicitud maliciosa al usuario:

    • Puede ser un enlace, una imagen, un formulario oculto o un script.

  3. El navegador del usuario envía la solicitud al servidor, incluyendo automáticamente las cookies de autenticación del usuario.

  4. El servidor procesa la solicitud como si hubiera sido legítimamente iniciada por el usuario.


🛠️ Mecanismo de ataque

Ejemplo de formulario malicioso:

<form action="http://victim.com/transfer" method="POST">
    <input type="hidden" name="account" value="attacker_account">
    <input type="hidden" name="amount" value="1000">
    <input type="submit" value="Enviar">
</form>

El atacante puede engañar al usuario para que cargue esta página o enlace, lo que provocará una transferencia no autorizada.


🎯 Impacto

  • Transacciones no autorizadas: Transferencias de dinero o compras.

  • Modificación de datos: Cambiar contraseñas, correos electrónicos o configuraciones de cuenta.

  • Robo de información: Acceso a datos personales o confidenciales.

  • Ejecución de acciones administrativas: Si el usuario atacado tiene privilegios altos, el impacto puede ser devastador.


📉 Puntaje CVSS v3

  • Vector de ataque: Red

  • Complejidad del ataque: Baja (no requiere autenticación)

  • Impacto en confidencialidad: Alto

  • Impacto en integridad: Alto

  • Impacto en disponibilidad: Medio

  • Puntaje CVSS v3: 7.0 - 8.8 (Alto) ⚠️


🧑‍💻 Ejemplo práctico

Código vulnerable en PHP:

<?php
    if ($_POST['amount'] && $_POST['account']) {
        $account = $_POST['account'];
        $amount = $_POST['amount'];
        
        // Procesa la transferencia sin verificar la legitimidad de la solicitud
        transfer($account, $amount);
        echo "Transferencia completada.";
    }
?>

Ataque: El atacante envía un enlace al usuario, que carga automáticamente el formulario malicioso:

<img src="http://victim.com/transfer?account=attacker&amount=1000" />

🛡️ ¿Cómo prevenir CSRF?

1️⃣ Tokens CSRF

Genera un token único para cada sesión o formulario y verifica que esté presente en cada solicitud.

Ejemplo en PHP:

<?php
    session_start();
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
?>

<form method="POST" action="/transfer">
    <input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
    <!-- Otros campos -->
    <button type="submit">Enviar</button>
</form>

En el servidor, verifica el token:

<?php
    session_start();
    if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
        die("Solicitud inválida.");
    }
?>

2️⃣ Validación del encabezado de referencia (Referer o Origin)

Verifica que las solicitudes provengan de una URL legítima:

if (!isset($_SERVER['HTTP_ORIGIN']) || $_SERVER['HTTP_ORIGIN'] !== 'http://victim.com') {
    die("Solicitud no autorizada.");
}

3️⃣ Métodos seguros

Evita realizar operaciones críticas con métodos GET. Usa POST para cambios de estado.

4️⃣ Implementar SameSite Cookies

Configura las cookies para que solo se envíen en solicitudes del mismo sitio:

setcookie('session', $value, ['samesite' => 'Strict']);

5️⃣ Uso de bibliotecas seguras

Frameworks como Django o Laravel tienen mecanismos CSRF incorporados. Aprovéchalos.

6️⃣ Autenticación en cada acción sensible

Solicita al usuario autenticarse nuevamente para acciones críticas como transferencias.


💡 Dato extra: CSRF es más efectivo cuando los usuarios son administradores o tienen privilegios altos, ya que el atacante puede realizar acciones devastadoras.

🚨 Nota importante: Aunque los tokens CSRF son la defensa más efectiva, deben usarse correctamente y almacenarse de manera segura.

Última actualización

¿Te fue útil?