La falsificación de solicitudes de sitios cruzados (también conocida como ataques CSRF o XSRF) es un ataque que permite a los atacantes ejecutar acciones no deseadas en una aplicación web en la que un usuario está autenticado actualmente. El ataque es posible cuando la aplicación de destino no valida correctamente el origen de la solicitud y se basa únicamente en la existencia de una sesión válida entre el navegador de la víctima y el servidor de la aplicación.
En el escenario más común de un ataque CSRF, un usuario que haya iniciado sesión accederá a una página web adicional proporcionada por el atacante en otra pestaña del navegador. Esta página apuntará de inmediato a una función sensible dentro de la aplicación, que todavía está abierta en la otra pestaña, mediante el envío de una solicitud especialmente diseñada. Dado que la solicitud se envía desde el mismo navegador, la aplicación vulnerable aceptará la solicitud y ejecutará la acción.
LaprotecciónadecuadadeCSRFsebasaenevitarquelosatacantespuedancrearunasolicitudgranulardeaccionesenunsistema.Unasoluciónparaestetipodeataqueesimplementartokensaleatoriosúnicosparaformulariossensibles.Paracadaenvíodeformulario,eltokendebevalidarseenelladodelservidor.
Comonotaalmargen,estostokenssiempredebenenviarseutilizandoelmétodoPOST.Normalmentesesuministrancomouncampodeformulariooculto.
AquíhayunejemplodeimplementacióndeCSRFparaPHP:
- GenerandountokenCSRFseguroenPHP
functiongenerateCSRFKey($key){$token=base64_encode(openssl_random_pseudo_bytes(16));$_SESSION['csrf_'.$key]=$token;return$token;}
¡Puedeestartentadoausarrand()ouniqid()peroambosafirmanespecíficamentequeestasfuncionesnodebenusarseparagenerartokensseguros!Además,base64_encode()soloseusaparaasegurarsedequeelvalornorompaningúncódigoHTML.
La verificación de un token enviado es válida:
function checkCSRFKey($key, $value) {
if (!isset($_SESSION['csrf_' . $key]))
return false;
if (!$value)
return false;
if ($_SESSION['csrf_' . $key] !== $value)
return false;
unset($_SESSION['csrf_' . $key]);
return true;
}
El código anterior se puede usar para agregar un token único a cualquier formulario usando:
" name="token">
- El código para verificar en el lado del servidor si el token suministrado es válido:
$token = $_POST['token'];
if (checkCSRFKey('settings', $token)) {
// Handle error
}