Pergunta

Quais são algumas diretrizes para manter a segurança responsável da sessão com PHP?Há informações por toda a web e já é hora de colocar tudo em um só lugar!

Foi útil?

Solução

Há algumas coisas que você pode fazer para manter sua sessão segura:

  1. Use SSL ao autenticar usuários ou realizar operações confidenciais.
  2. Gere novamente o ID da sessão sempre que o nível de segurança for alterado (como fazer login).Você pode até regenerar o ID da sessão a cada solicitação, se desejar.
  3. Faça com que as sessões expirem
  4. Não use registros globais
  5. Armazene detalhes de autenticação no servidor.Ou seja, não envie detalhes como nome de usuário no cookie.
  6. Verifica a $_SERVER['HTTP_USER_AGENT'].Isso adiciona uma pequena barreira ao sequestro de sessão.Você também pode verificar o endereço IP.Mas isso causa problemas para usuários que alteram o endereço IP devido ao balanceamento de carga em múltiplas conexões de Internet, etc. (que é o caso em nosso ambiente aqui).
  7. Bloqueie o acesso às sessões no sistema de arquivos ou use tratamento de sessão personalizado
  8. Para operações confidenciais, considere exigir que os usuários logados forneçam novamente seus detalhes de autenticação

Outras dicas

Uma orientação é ligar session_regenerate_id sempre que o nível de segurança de uma sessão muda.Isso ajuda a evitar o sequestro de sessão.

Meus dois (ou mais) centavos:

  • Não acredite em ninguém
  • Entrada de filtro, saída de escape (cookie, dados da sessão também são sua entrada)
  • Evite XSS (mantenha seu HTML bem formado, dê uma olhada em PHPTAL ou Purificador HTML)
  • Defesa em profundidade
  • Não exponha dados

Existe um livro pequeno, mas bom, sobre esse assunto: Segurança PHP Essencial por Chris Shiflett.

Segurança PHP essencial http://shiflett.org/images/essential-php-security-small.png

Na página inicial do livro você encontrará alguns exemplos de código interessantes e capítulos de amostra.

Você pode usar a técnica mencionada acima (IP e UserAgent), descrita aqui: Como evitar roubo de identidade

Acho que um dos principais problemas (que está sendo abordado no PHP 6) é o register_globals.Neste momento, um dos métodos padrão usados ​​para evitar register_globals é usar o $_REQUEST, $_GET ou $_POST matrizes.

A maneira "correta" de fazer isso (a partir do 5.2, embora seja um pouco problemático, mas estável a partir do 6, que será lançado em breve) é através filtros.

Então, em vez de:

$username = $_POST["username"];

você faria:

$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);

ou mesmo apenas:

$username = filter_input(INPUT_POST, 'username');

Este documento de fixação da sessão tem indicações muito boas de onde o ataque pode ocorrer.Veja também página de fixação de sessão na Wikipedia.

Usar o endereço IP não é realmente a melhor ideia na minha experiência.Por exemplo;meu escritório tem dois endereços IP que são usados ​​dependendo da carga e constantemente enfrentamos problemas ao usar endereços IP.

Em vez disso, optei por armazenar as sessões em um banco de dados separado para os domínios dos meus servidores.Dessa forma, ninguém no sistema de arquivos tem acesso às informações da sessão.Isso foi realmente útil com o phpBB antes do 3.0 (eles já consertaram isso), mas ainda é uma boa ideia, eu acho.

Isso é bastante trivial e óbvio, mas certifique-se de sessão_destruir após cada uso.Isso pode ser difícil de implementar se o usuário não efetuar logout explicitamente, portanto, um cronômetro pode ser definido para fazer isso.

Aqui está um bom tutorial em setTimer() e clearTimer().

O principal problema com sessões PHP e segurança (além do sequestro de sessão) está no ambiente em que você está.Por padrão, o PHP armazena os dados da sessão em um arquivo no diretório temporário do sistema operacional.Sem qualquer pensamento ou planejamento especial, este é um diretório legível mundialmente, portanto todas as informações da sua sessão são públicas para qualquer pessoa com acesso ao servidor.

Quanto à manutenção de sessões em vários servidores.Nesse ponto, seria melhor mudar o PHP para sessões manipuladas pelo usuário, onde ele chama as funções fornecidas para CRUD (criar, ler, atualizar, excluir) os dados da sessão.Nesse ponto, você pode armazenar as informações da sessão em um banco de dados ou em uma solução semelhante a um memcache, para que todos os servidores de aplicativos tenham acesso aos dados.

Armazenar suas próprias sessões também pode ser vantajoso se você estiver em um servidor compartilhado, pois permitirá armazená-las no banco de dados, sobre o qual muitas vezes você tem mais controle do que o sistema de arquivos.

Eu configurei minhas sessões assim-

na página de login:

$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);

(frase definida em uma página de configuração)

depois, no cabeçalho que está presente em todo o resto do site:

session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) {       
    session_destroy();
    header('Location: http://website login page/');
    exit();     
}

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache adicionar cabeçalho:

X-XSS-Protection    1

Eu verificaria o IP e o User Agent para ver se eles mudam

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}

Se você usa session_set_save_handler() você pode definir seu próprio manipulador de sessão.Por exemplo, você poderia armazenar suas sessões no banco de dados.Consulte os comentários do php.net para obter exemplos de um manipulador de sessão de banco de dados.

Sessões de banco de dados também são boas se você tiver vários servidores, caso contrário, se estiver usando sessões baseadas em arquivos, será necessário garantir que cada servidor da Web tenha acesso ao mesmo sistema de arquivos para ler/gravar as sessões.

Você precisa ter certeza de que os dados da sessão estão seguros.Olhando seu php.ini ou usando phpinfo() você pode encontrar as configurações da sua sessão._session.save_path_ informa onde eles foram salvos.

Verifique a permissão da pasta e de seus pais.Não deve ser público (/tmp) ou acessível por outros sites no seu servidor compartilhado.

Supondo que você ainda queira usar a sessão php, você pode configurar o php para usar outra pasta alterando _session.save_path_ ou salvar os dados no banco de dados alterando _session.save_handler_ .

Você pode definir _session.save_path_ em seu php.ini (alguns provedores permitem) ou para apache + mod_php, em um arquivo .htaccess na pasta raiz do seu site:php_value session.save_path "/home/example.com/html/session".Você também pode configurá-lo em tempo de execução com _session_save_path()_ .

Verificar Tutorial de Chris Shiflett ou Zend_Session_SaveHandler_DbTable para definir um manipulador de sessão alternativo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top