SecureBank - Simulador CSRF
Laboratorio interactivo para entender y prevenir ataques Cross-Site Request Forgery (CSRF)
Laboratorio interactivo para entender y prevenir ataques Cross-Site Request Forgery (CSRF)
| Fecha | Destinatario | Monto | Estado |
|---|
Aprende todo sobre Cross-Site Request Forgery y cómo protegerte
CSRF (Cross-Site Request Forgery) es un ataque que engaña al navegador de un usuario para que ejecute acciones no deseadas en una aplicación web donde el usuario está autenticado.
CSRF es una vulnerabilidad que permite a un atacante inducir a los usuarios a realizar acciones que no tienen la intención de realizar. En un ataque CSRF exitoso, el atacante hace que la víctima ejecute una acción no deseada en una aplicación web en la que la víctima está autenticada.
El objetivo principal es aprovecharse de la confianza que una aplicación web tiene en el navegador del usuario. Si un usuario está autenticado en un sitio web, el navegador enviará automáticamente las cookies de sesión con cada solicitud a ese dominio.
OWASP Top 10 2021: A01:2021 - Broken Access Control (incluye CSRF)
Prevalencia: Aproximadamente 94% de aplicaciones tienen alguna forma de control de acceso roto
Impacto: Promedio de 5.4 Common Weakness Enumerations (CWEs) por aplicación
Representación visual del flujo completo de un ataque CSRF desde la perspectiva del atacante y la víctima
<!-- Formulario oculto que se envía automáticamente -->
<form action="https://banco.com/transfer" method="POST" style="display:none;">
<input name="to" value="cuenta-atacante">
<input name="amount" value="1000">
<input name="currency" value="EUR">
</form>
<script>
// Envío automático al cargar la página
document.forms[0].submit();
</script>
La aplicación debe usar cookies para autenticación. El navegador las enviará automáticamente con cada solicitud al dominio, incluso si la solicitud se origina desde otro sitio.
La aplicación no verifica que la solicitud provenga del sitio legítimo. No valida headers como Origin o Referer.
No hay tokens únicos que vinculen la solicitud con la sesión del usuario. Cada formulario debería incluir un token secreto impredecible.
Las acciones sensibles tienen parámetros predecibles que un atacante puede replicar fácilmente (nombres de campo, formatos, etc.).
Las cookies no tienen el atributo SameSite configurado o están configuradas como None, permitiendo solicitudes cross-site.
La aplicación permite cambios de estado usando métodos GET, o acepta tanto GET como POST para acciones sensibles.
Implementar tokens únicos, impredecibles y vinculados a la sesión del usuario.
<input type="hidden" name="csrf_token" value="abc123xyz789">
if ($_POST['csrf_token'] !== $_SESSION['csrf_token']) {
die('CSRF token inválido');
}
Usar el atributo SameSite para prevenir el envío de cookies en solicitudes cross-site.
Set-Cookie: sessionid=abc123; SameSite=Strict; Secure; HttpOnly
Strict: Nunca envía cookies cross-siteLax: Solo en navegación top-levelNone: Permite cross-site (requiere Secure)Validar las cabeceras Origin y Referer para asegurar que las solicitudes provienen del dominio correcto.
if ($_SERVER['HTTP_ORIGIN'] !== 'https://mibanco.com') {
http_response_code(403);
die('Origen no autorizado');
}
Implementar cabeceras HTTP adicionales para mejorar la seguridad.
Content-Security-Policy: default-src 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Para acciones críticas, requerir confirmación adicional como re-autenticación o 2FA.
// Para transferencias > $1000, requerir contraseña
if ($amount > 1000 && !verify_password($_POST['password'])) {
die('Confirmación de contraseña requerida');
}
Configurar CORS de manera restrictiva para limitar solicitudes cross-origin.
Access-Control-Allow-Origin: https://mibanco.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: Content-Type, Authorization
Herramienta profesional para pruebas de seguridad web con extensiones específicas para CSRF.
Herramienta gratuita de seguridad web con capacidades de detección CSRF.
Herramienta específica para pruebas de CSRF desarrollada por OWASP.
java -jar CSRFTester.jar
# 1. Configurar proxy
# 2. Navegar por la aplicación
# 3. Generar formularios de prueba
Scripts personalizados para automatizar pruebas CSRF.
import requests
# Probar CSRF en endpoint
response = requests.post(
'https://target.com/transfer',
data={'to': 'attacker', 'amount': 1000},
cookies={'session': 'victim_session'}
)
print(f"Status: {response.status_code}")
Ejemplo clásico de CSRF para transferencias financieras.
POST /transfer HTTP/1.1
Host: banco.com
Content-Type: application/x-www-form-urlencoded
Cookie: session=abc123
to=1234567890&amount=100¤cy=EUR
<form action="https://banco.com/transfer" method="POST">
<input name="to" value="atacante123">
<input name="amount" value="5000">
<input name="currency" value="EUR">
<input type="submit" value="¡Gana $1000!">
</form>
Ataque para cambiar credenciales de usuario.
<img src="https://target.com/change-password?new=hacked123"
style="display:none;">
<!-- La imagen "cargará" ejecutando el cambio -->
Realizar compras no autorizadas en e-commerce.
fetch('https://tienda.com/buy', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
product: 'expensive_item',
quantity: 10
})
});
Ejemplo de formulario protegido contra CSRF.
<form action="/transfer" method="POST">
<!-- Token Anti-CSRF -->
<input type="hidden" name="csrf_token"
value="<?= $_SESSION['csrf_token'] ?>">
<input name="to" required>
<input name="amount" type="number" required>
<button type="submit">Transferir</button>
</form>
// Verificar token CSRF
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
die('Token CSRF inválido');
}
// Verificar origen
if ($_SERVER['HTTP_ORIGIN'] !== 'https://mibanco.com') {
die('Origen no autorizado');
}
// Procesar transferencia segura
process_transfer($_POST['to'], $_POST['amount']);