Estoy tratando de agregar algo de seguridad a los formularios de mi sitio web. Uno de los formularios utiliza AJAX y el otro es un sencillo formulario de "contacto". Estoy intentando agregar un token CSRF. El problema que tengo es que el token solo aparece en el "valor" de HTML algunas veces. El resto del tiempo, el valor está vacío. Aquí está el código que estoy usando en el formulario AJAX:
PHP:
if (!isset($_SESSION)) {
session_start();
$_SESSION['formStarted'] = true;
}
if (!isset($_SESSION['token']))
{$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
}
HTML
<form>
//...
<input type="hidden" name="token" value="<?php echo $token; ?>" />
//...
</form>
¿Alguna sugerencia?
token_time
para qué se usa?token_time
. Iba a limitar el tiempo dentro del cual un token es válido, pero aún no he implementado completamente el código. En aras de la claridad, lo eliminé de la pregunta anterior.Respuestas:
Para el código de seguridad, no genere sus tokens de esta manera:
$token = md5(uniqid(rand(), TRUE));
rand()
es predecibleuniqid()
solo suma hasta 29 bits de entropíamd5()
no agrega entropía, simplemente la mezcla de manera deterministaProbar esto:
Generando un token CSRF
PHP 7
Nota al margen: Uno de los proyectos de código abierto de mi empleador es una iniciativa de backport
random_bytes()
yrandom_int()
en proyectos PHP 5. Tiene licencia del MIT y está disponible en Github y Composer como paragonie / random_compat .PHP 5.3+ (o con ext-mcrypt)
Verificación del token CSRF
No solo use
==
o incluso===
usehash_equals()
(solo PHP 5.6+, pero disponible para versiones anteriores con la biblioteca hash-compat ).Yendo más lejos con tokens por formulario
Puede restringir aún más los tokens para que solo estén disponibles para un formulario en particular usando
hash_hmac()
. HMAC es una función hash con clave particular que es segura de usar, incluso con funciones hash más débiles (por ejemplo, MD5). Sin embargo, recomiendo usar la familia SHA-2 de funciones hash en su lugar.Primero, genere un segundo token para usar como clave HMAC, luego use una lógica como esta para representarlo:
Y luego usando una operación congruente al verificar el token:
Los tokens generados para un formulario no se pueden reutilizar en otro contexto sin saberlo
$_SESSION['second_token']
. Es importante que utilice un token diferente como clave HMAC que el que acaba de colocar en la página.Bono: Enfoque híbrido + Integración Twig
Cualquiera que use el motor de plantillas Twig puede beneficiarse de una estrategia dual simplificada al agregar este filtro a su entorno Twig:
Con esta función Twig, puede usar ambos tokens de propósito general así:
O la variante bloqueada:
Twig solo se ocupa del renderizado de plantillas; aún debe validar los tokens correctamente. En mi opinión, la estrategia Twig ofrece una mayor flexibilidad y simplicidad, al tiempo que mantiene la posibilidad de máxima seguridad.
Tokens CSRF de un solo uso
Si tiene un requisito de seguridad de que cada token CSRF se pueda usar exactamente una vez, la estrategia más simple lo regenerará después de cada validación exitosa. Sin embargo, hacerlo invalidará todos los tokens anteriores, lo que no se combina bien con las personas que navegan por varias pestañas a la vez.
Paragon Initiative Enterprises mantiene una biblioteca Anti-CSRF para estos casos de esquina. Funciona con tokens de un solo uso por formulario, exclusivamente. Cuando se almacenan suficientes tokens en los datos de la sesión (configuración predeterminada: 65535), se eliminarán primero los tokens no canjeados más antiguos.
fuente
Parece que necesitas un else con tu if.
fuente
md5(uniqid(rand(), TRUE));
en contextos de seguridad.La variable
$token
no se recupera de la sesión cuando está allífuente