Quais são algumas diretrizes para manter a segurança da sessão responsável com o PHP? Há informações em toda a web e já é hora de tudo chegar em um só lugar!
Quais são algumas diretrizes para manter a segurança da sessão responsável com o PHP? Há informações em toda a web e já é hora de tudo chegar em um só lugar!
Respostas:
Existem algumas coisas a fazer para manter sua sessão segura:
$_SERVER['HTTP_USER_AGENT']
. Isso adiciona uma pequena barreira ao seqüestro de sessões. Você também pode verificar o endereço IP. Mas isso causa problemas para os usuários que alteram o endereço IP devido ao balanceamento de carga em várias conexões com a Internet, etc. (que é o caso em nosso ambiente aqui).Uma diretriz é chamar session_regenerate_id toda vez que o nível de segurança de uma sessão for alterado. Isso ajuda a impedir o seqüestro de sessões.
Meus dois (ou mais) centavos:
Há um pequeno mas bom livro sobre este tópico: Essential PHP Security, de Chris Shiflett .
Segurança essencial do PHP http://shiflett.org/images/essential-php-security-small.png
Na home page do livro, você encontrará alguns exemplos de código interessantes e exemplos de capítulos.
Você pode usar a técnica mencionada acima (IP e UserAgent), descrita aqui: Como evitar o roubo de identidade
Eu acho que um dos principais problemas (que está sendo tratado no PHP 6) é o register_globals. Neste momento, um dos métodos convencionais usado para evitar register_globals
é usar os $_REQUEST
, $_GET
ou $_POST
matrizes.
A maneira "correta" de fazê-lo (a partir da versão 5.2, embora seja um pouco problemática, mas estável a partir da 6, que será lançada em breve) é através de 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 muito bons indicadores de onde o ataque pode ocorrer. Veja também a página de fixação de sessões 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 usando endereços IP.
Em vez disso, optei por armazenar as sessões em um banco de dados separado para os domínios em meus servidores. Dessa forma, ninguém no sistema de arquivos tem acesso a essas informações da sessão. Isso foi realmente útil com o phpBB antes da versão 3.0 (eles já corrigiram isso), mas ainda é uma boa idéia, 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 fizer logout explicitamente, portanto, um timer pode ser configurado para fazer isso.
Aqui está um bom tutorial sobre setTimer () e clearTimer ().
O principal problema com as sessões e segurança do PHP (além do seqüestro de sessão) vem com o 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 nenhum 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 alternar o PHP para sessões manipuladas pelo usuário, onde ele chama suas 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 ao 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 ele permitirá armazená-lo no banco de dados, que muitas vezes você tem mais controle sobre 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 do restante 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();
}
session.cookie_httponly = 1
change session name from default PHPSESSID
X-XSS-Protection 1
X-XSS-Protection
não é realmente útil. De fato, o próprio algoritmo de proteção poderia ser explorado, tornando-o pior do que antes.
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ê usar session_set_save_handler (), poderá definir seu próprio manipulador de sessões. Por exemplo, você pode armazenar suas sessões no banco de dados. Consulte os comentários do php.net para exemplos de um manipulador de sessões de banco de dados.
As 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 para o seu php.ini ou usando o phpinfo (), você pode encontrar as configurações da sessão. _session.save_path_ informa onde eles são salvos.
Verifique a permissão da pasta e de seus pais. Não deve ser público (/ tmp) ou estar acessível por outros sites em seu servidor compartilhado.
Supondo que você ainda deseja 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 ser capaz de definir _session.save_path_ no seu php.ini (alguns provedores de permitir que ele) ou para apache + mod_php, em um arquivo .htaccess na pasta raiz do 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 () _.
Verifique o tutorial de Chris Shiflett ou Zend_Session_SaveHandler_DbTable para definir um manipulador de sessão alternativo.