+4

Segurança de Sessão no PHP

criado por Douglas V. Pasqua em 15/04/2010 5:36pm
Session Fixation

Quando o usuário acessa um página de sua aplicação em que é chamada a função session_start(), uma nova sessão é criada para o usuário. O PHP gera um identificador randômico referente a conexão do usuário e então envia um header Set-Cookie para ele contendo o identificador. Por padrão o nome do cookie é PHPSESSID. Nas requisições seguintes o navegador do usuário envia o cookie para o servidor e dessa a forma a aplicação é capaz de idenficá-lo.

Porém é possível setar o identificador da sessão manualmente através da query string. Consequentemente todas as próximas requisições irão usar esse identificador. Para explorar essa vulnerabiliade o atacante cria uma página contendo um link para o site no qual deseja obter acesso à sessão da vítima. Exemplo:

<a href="http://www.dominio-exemplo.com?PHPSESSID=987654321">Acessar</a>

Se o usuário clica no link, acessa o site e loga em alguma área restrita ele estará usando o identificador criado pelo atacante. Dessa forma é possível que o atacante obtenha acesso a conta do usuário logado no site, simplesmente usando o identificador criado por ele.
Este ataque é conhecido como Session Fixation.

Nas versões mais recentes do php as opções do php.ini: session.use_trans_sid e session.use_only_cookies vem setadas de certa forma que impedem que o ataque aconteça.

Para testar a vulnerabilidade abaixo, você deve setar a opção session.use_trans_sid para On e session.use_only_cookies para Off no php.ini. O desenvolvedor que pretende possiblitar a utilização de sessão em navegadores que tem cookies desabilitados devem setar as diretivas dessa maneira. Acredito que hoje em dia é muito raro usuários que estão navegando com a opção de cookies desativada. Portanto o php já vem configurado de modo “seguro”.

Testando a vulnerabilidade:

<?php
session_start();

if (!array_key_exists('visitas', $_SESSION))
    $_SESSION['visitas'] = 1;
else
    $_SESSION['visitas']++;

echo $_SESSION['visitas'];
?>

Quando você acessar essa página pela primeira vez você irá visualizar o número 1. Para cada acesso subsequente você verá o número sendo incrementado por mais um.

Para demonstrar a vulnerabilidade, feche todos os browsers, delete os cookies e depois abra novamente, acrescentando ?PHPSESSID=654321 no final da URL. Na primeira vez você verá o número 1. A partir de um outro computador ou um outro navegador, acesse a página acrescentando ?PHPSESSID=654321 no final da URL. Dessa vez, você não verá o número 1, mas sim o número subsequente ao último acesso realizado na sessão. O que aconteceu aqui é que o segundo “usuário” obteve acesso à sessão do primeiro usuário.

Para se proteger contra o ataque no nível de aplicação é simples. Toda vez que o usuário autenticar ou mudar o seu previlégio simplesmente gere novamente o identificador da sessão. Isso é feito através da função session_regenerate_id(). Dessa forma o usuário irá utilizar um identificador novo quando logar no site, diferente do inicial quando acessou a página pela primeira vez. O atacante não terá como saber o novo identificador caso ele use a técnica de fixar o identificador da sessão. Exemplo:

<?php
/* proteger contra session fixation. Gerar novo
  identificador ao logar no sistema. */

if (usuario_autenticado()) {
    session_regenerate_id();
}
?>

Comentários:

Mostrando 1 - 5 de 5 comentários
Hernani disse:
Muito Bom!
11/11/2016 9:03am (~2 meses atrás)

Juan disse:
Muito legal o artigo!

Obrigado por compartilhar seu conhecimento.
08/04/2014 3:54pm (~2 anos atrás)

Thyago Silva disse:
Perfeito! Valeu pelas recomendações

http://www.cupom.net
18/06/2013 1:37am (~3 anos atrás)

André Luis disse:
Muito bom o artigo, sou inciante na área de web e esse artigo já me deu uma boa base.
01/06/2013 10:36pm (~3 anos atrás)

mauricio disse:
ótimo artigo.
24/02/2013 10:34pm (~3 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)