Protección CSRF
Reglas
- Establece
SameSite=Lax en todas las cookies — esto bloquea la mayoría de los ataques CSRF de forma predeterminada
- Utiliza
SameSite=Strict para acciones altamente sensibles (eliminación de cuenta, cambio de contraseña)
- Implementa el patrón de doble envío de cookies para APIs personalizadas: token CSRF en cookie + encabezado de solicitud
- Incluye tokens CSRF en todos los formularios HTML que realicen acciones de cambio de estado
- Verifica los encabezados
Origin y Referer en las solicitudes de cambio de estado como defensa en profundidad
- Las Server Actions de Next.js y las form actions de SvelteKit manejan CSRF automáticamente — utilízalas
- Para SPA: envía el token CSRF en un encabezado personalizado (
X-CSRF-Token) — los navegadores bloquean los encabezados personalizados de origen cruzado de forma predeterminada
import crypto from "crypto";
function generateCsrfToken(res) {
const token = crypto.randomBytes(32).toString("hex");
res.cookie("csrf_token", token, { httpOnly: false, sameSite: "strict", secure: true });
return token;
}
function verifyCsrf(req) {
const cookieToken = req.cookies.csrf_token;
const headerToken = req.headers["x-csrf-token"];
if (!cookieToken || cookieToken !== headerToken) {
throw new Error("Falló la validación CSRF");
}
}
Evitar
- Confiar únicamente en la autenticación basada en cookies sin protección CSRF — cualquier sitio puede enviar formularios a tus puntos finales
- Tokens CSRF que nunca rotan — un token filtrado compromete todas las solicitudes futuras
- Solicitudes GET que cambian de estado — la protección CSRF solo funciona en POST/PUT/DELETE porque GET omite SameSite=Lax
- Deshabilitar la protección CSRF porque "es solo una API" — si hay cookies involucradas, CSRF aplica