Qual é a melhor maneira de evitar o seqüestro de session?

Especificamente, isso ocorre em relação ao uso de um cookie de session do cliente para identificar uma session no servidor.

É a melhor resposta para usar a criptografia SSL / HTTPS para todo o site, e você tem a melhor garantia de que nenhum homem nos ataques do meio será capaz de farejar um cookie de session do cliente existente?

E talvez o segundo melhor para usar algum tipo de criptografia no próprio valor da session armazenado no cookie de session?

Se um usuário mal-intencionado tiver access físico a uma máquina, ele ainda poderá consultar o sistema de arquivos para recuperar um cookie de session válido e usá-lo para seqüestrar uma session?

Criptografar o valor da session terá efeito zero. O cookie de session já é um valor arbitrário, criptografando-o apenas gerará outro valor arbitrário que pode ser detectado.

A única solução real é HTTPS. Se você não quiser fazer SSL em todo o seu site (talvez você tenha problemas de desempenho), talvez seja possível se safar apenas com SSL protegendo as áreas sensíveis. Para fazer isso, primeiro certifique-se de que sua página de login é HTTPS. Quando um usuário efetua login, defina um cookie seguro (o que significa que o navegador só o transmitirá por um link SSL) além do cookie de session regular. Em seguida, quando um usuário visitar uma das áreas “confidenciais”, redirecione-as para HTTPS e verifique a presença desse cookie seguro. Um usuário real terá, um sequestrador de session não.

EDIT : Esta resposta foi originalmente escrita em 2008. É 2016 agora, e não há razão para não ter SSL em todo o site. Não há mais texto simples HTTP!

O SSL só ajuda com ataques de sniffing. Se um invasor tiver access à sua máquina, presumirei que ele também pode copiar seu cookie seguro.

No mínimo, certifique-se de que os cookies antigos perdem seu valor depois de um tempo. Mesmo um ataque hijaking bem-sucedido será frustrado quando o cookie parar de funcionar. Se o usuário tiver um cookie de uma session que efetuou login há mais de um mês, faça-o digitar novamente sua senha. Certifique-se de que sempre que um usuário clicar no link “sair” do site, o UUID da session antiga nunca poderá ser usado novamente.

Eu não tenho certeza se essa idéia vai funcionar, mas aqui vai: Adicione um número de série no seu cookie de session, talvez uma string como esta:

SessionUUID, Numero de Serie, Data / Hora Atual

Criptografe esta string e use-a como seu cookie de session. Altere regularmente o número de série – talvez quando o cookie tiver 5 minutos e, em seguida, emita novamente o cookie. Você poderia até reemitir em cada exibição de página, se quisesse. No lado do servidor, mantenha um registro do último numero serial que você emitiu para aquela session. Se alguém enviar um cookie com o número de série incorreto, isso significa que um invasor pode estar usando um cookie que interceptou anteriormente, portanto, invalide o UUID da session e solicite ao usuário que insira novamente sua senha e, em seguida, emita um novo cookie.

Lembre-se de que seu usuário pode ter mais de um computador para que eles possam ter mais de uma session ativa. Não faça algo que os force a efetuar login novamente toda vez que alternar entre computadores.

Você já pensou em ler um livro sobre segurança PHP? Altamente recomendado.

Eu tive muito sucesso com o seguinte método para sites não certificados SSL.

  1. Desative várias sessões na mesma conta, certificando-se de não verificar isso somente por endereço IP. Em vez disso, verifique pelo token gerado no login que é armazenado com a session de usuários no database, bem como o endereço IP, HTTP_USER_AGENT e assim por diante

  2. Usando hyperlinks baseados em Relação Gera um link (por exemplo, http://example.com/secure.php?token=2349df98sdf98a9asdf8fas98df8 ) O link é anexado com uma string MD5 salgada aleatória x-BYTE (tamanho preferencial), após o redirecionamento de página gerado aleatoriamente token corresponde a uma página solicitada.

    • Após o recarregamento, várias verificações são feitas.
    • Endereço IP de origem
    • HTTP_USER_AGENT
    • Token de Sessão
    • você entendeu.
  3. Cookie de autenticação de session com duração curta. como postado acima, um cookie contendo uma string segura, que é uma das referências diretas à validade das sessões, é uma boa ideia. Faça com que expire a cada x Minutos, reemitindo esse token e re-sincronizando a session com os novos Dados. Se houver alguma correspondência incorreta nos dados, faça o logout do usuário ou faça com que eles autentiquem novamente sua session.

Eu não sou de forma alguma um especialista no assunto, eu tive um pouco de experiência neste tópico em particular, espero que algo disso ajude alguém lá fora.

// Collect this information on every request $aip = $_SERVER['REMOTE_ADDR']; $bip = $_SERVER['HTTP_X_FORWARDED_FOR']; $agent = $_SERVER['HTTP_USER_AGENT']; session_start(); // Do this each time the user successfully logs in. $_SESSION['ident'] = hash("sha256", $aip . $bip . $agent); // Do this every time the client makes a request to the server, after authenticating $ident = hash("sha256", $aip . $bip . $agent); if ($ident != $_SESSION['ident']) { end_session(); header("Location: login.php"); // add some fancy pants GET/POST var headers for login.php, that lets you // know in the login page to notify the user of why they're being challenged // for login again, etc. } 

O que isto faz é capturar informações ‘contextuais’ sobre a session do usuário, informações que não devem mudar durante a vida de uma única session. Um usuário não vai estar em um computador nos EUA e na China ao mesmo tempo, certo? Portanto, se o endereço IP mudar repentinamente na mesma session, o que implica fortemente uma tentativa de seqüestro de session, então você protege a session finalizando a session e forçando o usuário a se autenticar novamente. Isso frustra a tentativa de invasão, o invasor também é forçado a fazer login em vez de ter access à session. Notificar o usuário da tentativa (ajax-lo um pouco) e vola, ligeiramente irritado + usuário informado e sua session / informação está protegida.

Lançamos o User Agent e o X-FORWARDED-FOR para fazer o melhor possível para capturar a exclusividade de uma session para sistemas atrás de proxies / redes. Você pode usar mais informações do que isso, sinta-se à vontade para ser criativo.

Não é 100%, mas é muito eficaz.

Você pode fazer mais para proteger as sessões, expirá-las, quando um usuário sair de um site e voltar a forçá-lo a fazer o login novamente, talvez. Você pode detectar um usuário saindo e voltando capturando um HTTP_REFERER em branco (o domínio foi typescript na barra de URL) ou verifique se o valor no HTTP_REFERER é igual ao seu domínio ou não (o usuário clicou em um link externo / criado para chegar ao seu local).

Expirar sessões, não deixe que permaneçam válidas indefinidamente.

Não confie em cookies, eles podem ser roubados, é um dos vetores de ataque para seqüestro de session.

Tente o protocolo Secure Cookie descrito neste documento por Liu, Kovacs, Huang e Gouda:

Como indicado no documento:

Um protocolo de cookie seguro que é executado entre um cliente e um servidor precisa fornecer os quatro serviços a seguir: autenticação, confidencialidade, integridade e anti-reprodução.

Quanto à facilidade de implantação:

Em termos de eficiência, nosso protocolo não envolve nenhuma consulta ao database ou criptografia de chave pública. Em termos de capacidade de implementação, nosso protocolo pode ser facilmente implantado em um servidor da Web existente e não requer nenhuma alteração na especificação do cookie da Internet.

Resumindo: é seguro, leve, funciona muito bem para mim.

Não há como evitar 100% de ataques à session, mas com alguma abordagem podemos reduzir o tempo para um invasor interromper a session.

Método para evitar ataques à session:

1 – sempre use session com certificado ssl;

2 – enviar o cookie de session apenas com o httponly definido como verdadeiro (impedir que o javascript acesse o cookie de session)

2 – use ID de session regenerada no login e logout (observação: não use a session regenerada em cada solicitação, pois se você tiver uma solicitação consecutiva de ajax, terá a chance de criar várias sessões.)

3 – definir um tempo limite da session

4 – armazene o agente do usuário do navegador em uma variável $ _SESSION e compare com $ _SERVER [‘HTTP_USER_AGENT’] em cada solicitação

5 – defina um cookie de token e defina o tempo de expiração desse cookie para 0 (até que o navegador seja fechado). Regenerar o valor do cookie para cada solicitação (para solicitação ajax, não gere novamente o cookie do token). EX:

  //set a token cookie if one not exist if(!isset($_COOKIE['user_token'])){ //generate a random string for cookie value $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM)); //set a session variable with that random string $_SESSION['user_token'] = $cookie_token; //set cookie with rand value setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true); } //set a sesison variable with request of www.example.com if(!isset($_SESSION['request'])){ $_SESSION['request'] = -1; } //increment $_SESSION['request'] with 1 for each request at www.example.com $_SESSION['request']++; //verify if $_SESSION['user_token'] it's equal with $_COOKIE['user_token'] only for $_SESSION['request'] > 0 if($_SESSION['request'] > 0){ // if it's equal then regenerete value of token cookie if not then destroy_session if($_SESSION['user_token'] === $_COOKIE['user_token']){ $cookie_token = bin2hex(mcrypt_create_iv('16' , MCRYPT_DEV_URANDOM)); $_SESSION['user_token'] = $cookie_token; setcookie('user_token', $cookie_token , 0 , '/' , 'donategame.com' , true , true); }else{ //code for session_destroy } } //prevent session hijaking with browser user agent if(!isset($_SESSION['user_agent'])){ $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT']; } if($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']){ die('session hijaking - user agent'); } 

note: não regenere o cookie do token com ajax request note: o código acima é um exemplo. observação: se os usuários fizerem logout, o token de cookie deverá ser destruído, assim como a session

6 – não é uma boa abordagem para usar o ip do usuário para evitar o agendamento de session porque alguns usuários mudam de ip a cada requisição. QUE AFETAM OS USUÁRIOS VÁLIDOS

7 – pessoalmente eu armazenar dados da session no database, cabe a você o método que você adotar

Se você encontrar erro na minha abordagem, por favor corrija-me. Se você tem mais maneiras de evitar hyjaking de session, por favor me diga.

Certifique-se de não usar números inteiros para IDs de session. É muito melhor usar um GUID ou alguma outra cadeia longa de caracteres gerada aleatoriamente.

Há muitas maneiras de criar proteção contra o seqüestro de session, no entanto, todas elas reduzem a satisfação do usuário ou não são seguras.

  • Verificações IP e / ou X-FORWARDED-FOR. Estes funcionam e são bastante seguros … mas imaginem a dor dos usuários. Eles vêm para um escritório com WiFi, recebem novo endereço IP e perdem a session. Tenho que entrar novamente.

  • O agente do usuário verifica. O mesmo que acima, a nova versão do navegador está fora e você perde uma session. Além disso, são muito fáceis de “hackear”. É trivial para os hackers enviarem strings UA falsas.

  • token de localStorage. No logon, gere um token, armazene-o no armazenamento do navegador e armazene-o no cookie criptografado (criptografado no lado do servidor). Isso não tem efeitos colaterais para o usuário (o localStorage persiste por meio de atualizações do navegador). Não é tão seguro – como é apenas segurança através da obscuridade. Além disso, você pode adicionar alguma lógica (criptografia / descriptografia) ao JS para ocultá-lo ainda mais.

  • Cookie reeditando. Este é provavelmente o caminho certo para fazê-lo. O truque é permitir que apenas um cliente use um cookie por vez. Assim, o usuário ativo terá o cookie reimpresso a cada hora ou menos. O cookie antigo é invalidado se um novo for emitido. Os hacks ainda são possíveis, mas muito mais difíceis de fazer – um hacker ou usuário válido terá access rejeitado.

Vamos considerar que, durante a fase de login, o cliente e o servidor podem concordar com um valor de sal secreto. Posteriormente, o servidor fornece um valor de contagem a cada atualização e espera que o cliente responda com o hash do (secret salt + count). O sequestrador em potencial não tem como obter esse valor secreto de sal e, portanto, não pode gerar o próximo hash.

AFAIK o object de session não está acessível no cliente, como é armazenado no servidor web. No entanto, o ID da session é armazenado como um Cookie e permite que o servidor da Web rastreie a session do usuário.

Para evitar seqüestro de session usando o id da session, você pode armazenar uma cadeia de hash dentro do object de session, feita usando uma combinação de dois atributos, remote addr e remote port, que podem ser acessados ​​no servidor web dentro do object request. Esses atributos vinculam a session do usuário ao navegador no qual o usuário efetuou login.

Se o usuário efetuar login em outro navegador ou em um modo de navegação anônima no mesmo sistema, o endereço IP permanecerá o mesmo, mas a porta será diferente. Portanto, quando o aplicativo é acessado, o usuário deve receber um ID de session diferente pelo servidor da web.

Abaixo está o código que implementei e testei copiando o ID da session de uma session para outra. Isso funciona muito bem. Se houver uma brecha, deixe-me saber como você a simulou.

 @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); String sessionKey = (String) session.getAttribute("sessionkey"); String remoteAddr = request.getRemoteAddr(); int remotePort = request.getRemotePort(); String sha256Hex = DigestUtils.sha256Hex(remoteAddr + remotePort); if (sessionKey == null || sessionKey.isEmpty()) { session.setAttribute("sessionkey", sha256Hex); // save mapping to memory to track which user attempted Application.userSessionMap.put(sha256Hex, remoteAddr + remotePort); } else if (!sha256Hex.equals(sessionKey)) { session.invalidate(); response.getWriter().append(Application.userSessionMap.get(sessionKey)); response.getWriter().append(" attempted to hijack session id ").append(request.getRequestedSessionId()); response.getWriter().append("of user ").append(Application.userSessionMap.get(sha256Hex)); return; } response.getWriter().append("Valid Session\n"); } 

Eu usei o algoritmo SHA-2 para alterar o valor usando o exemplo dado em SHA-256 Hashing no baeldung

Fico na expectativa dos seus comentários.

Para reduzir o risco, você também pode associar o IP de origem à session. Dessa forma, um invasor precisa estar na mesma rede privada para poder usar a session.

Verificar headers de referência também pode ser uma opção, mas eles são mais facilmente falsificados.

Proteger por:

 $ip=$_SERVER['REMOTE_ADDER']; $_SESSEION['ip']=$ip;