Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Conflitos de sessão PHP com AJAX


Se entendi corretamente, parece que você está configurando o token para cada solicitação. Meu palpite é que a página antiga ainda tem o token antigo. Eu verificaria se o token está definido antes de explodi-lo automaticamente.
 if (isset($_SESSION['token'])){
    //do nothing
 } else{
   $_SESSION['token'] = md5(rand());
 }

Editar Para responder a sua pergunta.

Em vez de usar apenas uma chave de "token", crie uma chave para cada sessão do navegador.
$_SESSION[$sessionId] = md5(rand());

O truque, é claro, será descobrir quando isso acontecer, porque se você não puder usar a sessão, você realmente não saberá se a solicitação está vindo de uma nova guia ou de uma antiga. Você pode usar a string de consulta para passar esse parâmetro. Basicamente, todas as solicitações teriam que ter esse parâmetro, caso contrário, você não associa uma sessão a elas.

por exemplo.
http://www.yoursite.com/somepage.php?sessionid=<some generated id>

Em última análise, o usuário pode brincar com isso, mas não tenho certeza se há alguma maneira de contornar isso.

Editar 2 Ok, aqui está o meu pensamento sobre como você deve fazer isso. Especialistas em segurança por aí, sintam-se à vontade para me xingar se eu tiver errado, como eu disse antes que não sou especialista, mas não parece que vou sair dessa sem sugerir algo;-)

O problema com o CSFR é que algum usuário mal-intencionado, Bob, pode criar um elemento em outro site que faz com que o navegador de Alice faça uma solicitação para algum outro site e, porque Alice fez login anteriormente e essas informações são armazenadas como um cookie ou Alice é reconhecido via sessão, o site executa a solicitação como se Alice tivesse solicitado. Por exemplo, se o banco de Alice for http://www.mybank.com , Bob poderia criar uma postagem no fórum que contém
<img srg="http://www.mybank.com/transferfunds.php?amount=1000&receiver=Bob" />

O banco de Alice reconheceria seu navegador como fazendo o pedido, pensando que era ela. Há algumas coisas importantes que precisam acontecer (juntos, qualquer uma dessas falhas fará com que o ataque falhe) para tornar isso um ataque viável (esses são os principais para entender como evitá-lo):
  1. Alice precisa estar logada no site do banco para que o banco se lembre dela. Isso pode acontecer em um cookie ("lembre-se de mim") ou por meio de sessão. No entanto, se ela fechar o navegador (encerrar a sessão) ou limpar os cookies, não haverá ameaça, pois o site do banco não a reconhecerá e negará a solicitação.
  2. Bob deve ser capaz de fornecer todos os parâmetros necessários para a solicitação, caso contrário, o site do banco negará a solicitação.

Para fornecer alguma noção de "estado" em cima de um protocolo sem estado (HTTP), você realmente não pode contornar o risco em (1). A menos que você faça com que as pessoas sempre cliquem em "sair" ou fechem a janela, etc., não há nada que você possa fazer para evitar armazenar informações no navegador ou na sessão. No entanto, você pode evitar que (2) seja um problema. Minha solução para isso (e tenho certeza de que existem muitas outras) é gerar um hash, como você está fazendo, e armazená-lo na sessão.

Por exemplo,
$_SESSION['token'] = md5(rand());

Então, o que você faz é anexar esse token a todos os seus links internos.

http://www.mysite.com/secure.php?token=giuwnrefviunslfghahgliuwnvwrgbaasd

Você NUNCA armazenar esse token na memória do navegador:ou seja, um cookie. Quando os pedidos são feitos, antes de fazer qualquer coisa, você verifica o token
//note, you'll want to sanitize user input, I'm just being brief
if ($_GET['token'] != $_SESSION['token']){
   //User either attempted to enter a link on their own or it's a CSRF attack
   header('HTTP/1.1 403 Forbidden');
 }else{
 //do whatever needs to be done
 }

A chave para isso é que todos os links em seu site incluirão o token. No entanto, Bob não tem como saber o que é esse token porque ele não está armazenado em um cookie no navegador. Se ele tentar criar um link para uma de suas páginas, ele conterá a chave errada ou não conterá nenhuma chave e você poderá negá-la. (Para ser justo, há uma chance de ele adivinhar corretamente o token para um usuário específico que por acaso visualiza seu código, mas é mais provável que ele pegue fogo.)

Não há necessidade de atribuir um tempo limite ao token, pois o token será obliterado quando o navegador for fechado e precisará ser gerado novamente quando o usuário visitar o site.