Estou tentando adicionar alguma segurança aos formulários do meu site. Um dos formulários usa AJAX e o outro é um formulário simples de "contato". Estou tentando adicionar um token CSRF. O problema que estou tendo é que o token só aparece no "valor" HTML algumas vezes. No resto do tempo, o valor está vazio. Aqui está o código que estou usando no formulário 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>
Alguma sugestão?
token_time
serve?token_time
. Eu ia limitar o tempo dentro do qual um token é válido, mas ainda não implementei totalmente o código. Para maior clareza, removi-o da pergunta acima.Respostas:
Para o código de segurança, não gere seus tokens desta forma:
$token = md5(uniqid(rand(), TRUE));
rand()
é previsíveluniqid()
adiciona apenas 29 bits de entropiamd5()
não adiciona entropia, apenas a mistura deterministicamenteExperimente isto:
Gerando um token CSRF
PHP 7
Sidenote: Um dos projetos de código aberto do meu empregador é uma iniciativa de backport
random_bytes()
erandom_int()
em projetos PHP 5. É licenciado pelo MIT e está disponível no Github e no Composer como paragonie / random_compat .PHP 5.3+ (ou com ext-mcrypt)
Verificando o token CSRF
Não use apenas
==
ou mesmo===
, usehash_equals()
(PHP 5.6+ apenas, mas disponível para versões anteriores com a biblioteca hash-compat ).Indo além com tokens por formulário
Você pode restringir ainda mais os tokens para que fiquem disponíveis apenas para um determinado formulário usando
hash_hmac()
. HMAC é uma função de hash com chave específica que é segura de usar, mesmo com funções de hash mais fracas (por exemplo, MD5). No entanto, recomendo usar a família SHA-2 de funções hash.Primeiro, gere um segundo token para usar como uma chave HMAC e, em seguida, use uma lógica como esta para renderizá-lo:
E, em seguida, usando uma operação congruente ao verificar o token:
Os tokens gerados para um formulário não podem ser reutilizados em outro contexto sem conhecimento
$_SESSION['second_token']
. É importante que você use um token separado como uma chave HMAC do que aquele que você acabou de colocar na página.Bônus: Abordagem Híbrida + Integração Twig
Qualquer pessoa que usa o mecanismo de modelagem Twig pode se beneficiar de uma estratégia dupla simplificada, adicionando este filtro ao ambiente Twig:
Com esta função Twig, você pode usar os tokens de uso geral como:
Ou a variante bloqueada:
O Twig está preocupado apenas com a renderização do template; você ainda deve validar os tokens corretamente. Na minha opinião, a estratégia Twig oferece maior flexibilidade e simplicidade, mantendo a possibilidade de máxima segurança.
Tokens CSRF de uso único
Se você tiver um requisito de segurança de que cada token CSRF possa ser usado exatamente uma vez, a estratégia mais simples é regenerá-lo após cada validação bem-sucedida. No entanto, isso invalidará todos os tokens anteriores, o que não combina bem com pessoas que navegam em várias guias ao mesmo tempo.
A Paragon Initiative Enterprises mantém uma biblioteca Anti-CSRF para esses casos secundários. Funciona exclusivamente com tokens de uso único por formulário. Quando tokens suficientes são armazenados nos dados da sessão (configuração padrão: 65535), os tokens não resgatados mais antigos são interrompidos primeiro.
fonte
Parece que você precisa de outro com seu if.
fonte
md5(uniqid(rand(), TRUE));
em contextos de segurança.A variável
$token
não está sendo recuperada da sessão quando está láfonte