mirror of
https://github.com/php/doc-pt_br.git
synced 2026-03-23 22:52:12 +01:00
775 lines
34 KiB
XML
775 lines
34 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- EN-Revision: 55e0481a24fd4d7db21b62f1885973edbca25e60 Maintainer: leonardolara Status: ready --><!-- CREDITS: fernandoc, felipe, leonardolara -->
|
|
|
|
<chapter xml:id="session.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Sessões e Segurança</title>
|
|
<para>
|
|
Links externos: <link xlink:href="&url.session-fixation;">Fixação de Sessão</link>
|
|
</para>
|
|
<para>
|
|
O gerenciamento de sessões HTTP representa o centro da segurança na web.
|
|
Todas as medídas possíveis de mitigação <emphasis>devem</emphasis>
|
|
ser adotadas para garantir que as sessões estão seguras.
|
|
Os desenvolvedores devem também habilitar/utilizar as medidas de segurança aplicáveis.
|
|
</para>
|
|
|
|
<sect1 xml:id="features.session.security.management">
|
|
<title>Gerencimento básico de sessão</title>
|
|
|
|
<sect2 xml:id="features.session.security.management.basic">
|
|
<title>Segurança da sessão</title>
|
|
|
|
<para>
|
|
O módulo de sessão não garante que a informação armazenada
|
|
em uma sessão seja visualizada apenas pelo usuário que criou a sessão. Medidas
|
|
adicionais devem ser tomadas para proteger a confidencialidade
|
|
da sessão, dependendo do valor associado à ela.
|
|
</para>
|
|
|
|
<para>
|
|
A importância dos dados carregados na sessão precisa ser
|
|
avaliada e proteções adicionais podem ser disparadas; isso normalmente
|
|
tem um preço, como alguns inconveninentes para o usuário.
|
|
Por exemplo, para proteger os usuários de uma tática simples de engenharia social,
|
|
a opção <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
precisa ser habilitada. Neste caso, os cookies devem obrigatoriamente estar habilitados
|
|
no lado do cliente, ou as sessões não irão funcionar.
|
|
</para>
|
|
|
|
<para>
|
|
Existem várias maneiras de expor um ID de sessão existente para
|
|
terceiros. Exemplos: injeção de JavaScript, ID de sessão nas URLs,
|
|
interceptação de pacotes, acesso físico ao dispositivo, etc.
|
|
Um ID de sessão exposto possibilita que terceiros tenham acesso a todos
|
|
os recursos que estão associados a um ID específico. Primeiro, URLs que contenham
|
|
IDs de sessão. Se houver ligações para um site ou recurso externo,
|
|
a URL que contém o ID de sessão pode ser armazenada nos registros
|
|
do site externo. Segundo, um atacante mais ativo pode interceptar
|
|
o tráfego de rede. Caso não estejam criptografados, os IDs de sessão serão transmitidos
|
|
em texto puro pela rede. A solução é implementar
|
|
SSL/TLS no servidor e torná-lo obrigatório para os usuários.
|
|
HSTS deve ser usado para uma melhor segurança.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Até mesmo o HTTPS não consegue proteger dados confidenciais em todos os momentos.
|
|
Por exemplo, as vulnerabilidades "CRIME" e "Beast" podem permitir que um
|
|
atacante leia os dados. Além disso, existem muitas redes que utilizam
|
|
proxy HTTPS MITM com o propósito de auditoria.
|
|
Atacantes também podem configurar um proxy semelhante.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.non-adaptive-session">
|
|
<title>Gerenciamento de sessão não adaptativo</title>
|
|
|
|
<para>
|
|
O gerenciador de sessão do PHP atualmente é adaptativo por padrão atualmente.
|
|
Os gerenciadores de sessão adaptativos possuem riscos adicionais.
|
|
</para>
|
|
|
|
<para>
|
|
Quando <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> está habilitada
|
|
e o manipulador de armazenamento de sessão suportá-la,
|
|
um ID de sessão que não inicializado é rejeitado, e um novo é criado.
|
|
Isso protege contra ataques que forçam o usuário a usar um ID de sessão conhecido.
|
|
Atacantes podem colar links ou enviar e-mail que contém ID de sessão.
|
|
Ex.: <literal>http://example.com/page.php?PHPSESSID=123456789</literal>, se
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link> estiver
|
|
habilitado, a vítima iniciará uma sessão usando o ID de sessão fornecido
|
|
pelo atacante.
|
|
A opção <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
mitiga este risco.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Um manipulador de armazenamento definido pelo usuário também pode suportar o modo de sessão estrita
|
|
implementando validação do ID de sessão. Todos os manipuladores de armazenamento definidos pelo usuário
|
|
devem implementar uma validação do ID de sessão.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
O cookie de ID de sessão pode ser definido usando os atributos domain, path, httponly e
|
|
secure; e a partir do PHP 7.3, SameSite.
|
|
<!-- Not exactly sure what the meaning here is - girgias -->
|
|
Existe uma certa precedência que é definida pelos navegadores.
|
|
Ao usar a precedência, o atacante pode definir um ID de sessão que
|
|
pode ser usado permanentemente. O uso de
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
não resolverá essa questão.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
mitiga este risco. Com
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On,
|
|
um ID de sessão não inicializado será recusado.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Apesar da opção
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
diminuir o risco do gerenciamento de sessão adaptativo, um atacante pode forçar
|
|
os usuários a usarem um ID de sessão inicializado e que foi criado pelo atacante.
|
|
Por exemplo, com injeção de JavaScript.
|
|
Esse tipo de ataque pode ser evitado seguindo as recomendações deste manual.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Ao seguir este manual, desenvolvedores devem habilitar a opção
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>,
|
|
e também usa um gerenciamento de sessão baseado em timestamp e gerar novamente um ID de sessão usando
|
|
<function>session_regenerate_id</function> com os procedimentos recomendados.
|
|
Se tudo isso for seguido, o ID de sessão gerado por um atacante
|
|
eventualmente será deletado.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Quando ocorre um acesso à uma sessão obsoleta, todos os dados da sessão
|
|
ativa devem ser salvos. Isso será útil para
|
|
uma investigação mais tarde. Será feito logout forçado do usuário
|
|
de todas as sessões, ou seja, o usuário será obrigado a se autenticar novamente.
|
|
Desta forma se evita que atacantes abusem de sessões roubadas.
|
|
</simpara>
|
|
</note>
|
|
|
|
<warning>
|
|
<simpara>
|
|
O acesso aos dados de sessões obsoletas nem sempre é por causa de ataques.
|
|
Redes instáveis e/ou remoção imediata de sessão ativa
|
|
farão com que usuários legítimos usem sessões obsoletas.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
A partir do PHP 7.1.0, <function>session_create_id</function> foi adicionado.
|
|
Essa função poderia ser usada para adicionar o ID do usuário como prefixo no ID de sessão para
|
|
acessar a sessão ativa do usuário de forma eficiente. Habilitar
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
é muito importante nesta configuração. Caso contrário, usuários mal intencionados podem definir
|
|
IDs de sessão maliciosos para outros usuários.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Usuários de versões anteriores ao PHP 7.1.0 <emphasis>devem</emphasis> usar
|
|
<acronym>CSPRNG</acronym>, como por exemplo <filename>/dev/urandom</filename> ou
|
|
<function>random_bytes</function>, e funções de hash para gerar um
|
|
novo ID de sessão. <function>session_create_id</function> possui
|
|
detecção de colisão e gera o ID de sessão de acordo com as
|
|
configurações INI de sessão.
|
|
O uso de <function>session_create_id</function> é preferível.
|
|
</simpara>
|
|
</note>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-id-regeneration">
|
|
<title>Renovação do ID de sessão</title>
|
|
|
|
<para>
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
é uma boa prevenção, mas não é o suficiente. Desenvolvedores devem usar
|
|
<function>session_regenerate_id</function> para a segurança da sessão.
|
|
</para>
|
|
|
|
<para>
|
|
A renovação do ID de sessão reduz o risco de roubo do ID de sessão, sendo assim,
|
|
<function>session_regenerate_id</function> deve ser chamada periodicamente.
|
|
Por exemplo, a renovação do ID de sessão a cada 15 minutos para a segurança de conteúdos sensíveis.
|
|
Mesmo se o ID de sessão for roubado, tanto a sessão do usuário legítimo
|
|
quanto a do atacante terão expirados.
|
|
Ou seja, o acesso do usuário ou do atacante
|
|
irá gerar erro de acesso à sessão obsoleta.
|
|
</para>
|
|
|
|
<para>
|
|
O ID de sessão <emphasis>deve</emphasis> ser renovado quando o privilégios do usuário
|
|
são elevados, por exemplo após o usuário se autenticar.
|
|
<function>session_regenerate_id</function> deve ser chamado antes de
|
|
salvar as informações de autenticação em <varname>$_SESSION</varname>.
|
|
(<function>session_regenerate_id</function> salva os dados da sessão
|
|
atual automaticamente com o intuito de salvar o timestamp/etc na sessão atual.)
|
|
Assegure-se de que apenas a nova sessão contenha flag autenticada.
|
|
</para>
|
|
|
|
<para>
|
|
Desenvolvedores <emphasis>não devem</emphasis> depender da expiração do ID de sessão proveniente de
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>.
|
|
Atacantes podem acessar o ID de sessão da vítima periodicamente para impedir que ele
|
|
expire e para poder continuar explorando o ID, inclusive as sessões autenticadas.
|
|
</para>
|
|
|
|
<para>
|
|
Ao invés disso, desenvolvedores devem implementar um gerenciamento de sessão baseada em timestamp.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Embora o gerenciador de sessão possa gerenciar o timestamp de forma transparente,
|
|
essa funcionalidade não está implementada. Dados de sessões antigas devem ser mantidos até a execução do
|
|
GC (coletor de lixo). Ao mesmo tempo, desenvolvedores devem assegurar-se de remover dados de sessões
|
|
obsoletas. Porém, os desenvolvedores não devem remover dados de sessões ativas imediatamente.
|
|
Isto é, <code>session_regenerate_id(true);</code>
|
|
e <function>session_destroy</function> nunca devem ser chamados juntos para uma sessão ativa.
|
|
Isso pode soar contraditório, mas é um requisito obrigatório.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
<function>session_regenerate_id</function> <emphasis>não</emphasis>
|
|
apaga sessão antiga por padrão.
|
|
Uma sessão obsoleta e autenticada pode estar disponível para uso.
|
|
Os desenvolvedores devem impedir que sessões desatualizadas sejam utilizadas por qualquer pessoa.
|
|
Eles devem impedir acesso acesso aos dados de sessões obsoletas por conta própria utilizando timestamps.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
A remoção repentina de sessão ativa produz efeitos colaterais indesejados.
|
|
A sessão pode desaparecer quando houver conexões concorrentes
|
|
em uma aplicação web e/ou a rede estiver instável.
|
|
</simpara>
|
|
<simpara>
|
|
Possíveis acessos maliciosos também não podem ser detectados com a remoção imediata de sessões ativas.
|
|
</simpara>
|
|
<simpara>
|
|
Ao invés de remover a sessão antiga imediatamente,
|
|
deve ser configurado, na <varname>$_SESSION</varname>, um tempo curto (timestamp) para a expiração
|
|
e proibir acesso aos dados da sessão (essa implementação é por contra própria).
|
|
</simpara>
|
|
<simpara>
|
|
O acesso aos dados de sessões antigas não deve ser bloqueado imediatamente depois de executar
|
|
<function>session_regenerate_id</function>. O acesso deve ser bloqueado
|
|
um pouco depois, como por exemplo, alguns segundos depois para redes estáveis, como redes cabeadas,
|
|
e alguns minutos depois para redes instáveis como celulares ou sem Wi-Fi.
|
|
</simpara>
|
|
<simpara>
|
|
Se um usuário tentar acessar uma sessão obsoleta (que já tenha expirado), o acesso deve ser proibido.
|
|
É recomendável que seja removido o status de autenticação de todas as sessões do usuário,
|
|
porque é provável que seja um ataque.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
O uso adequado de <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
|
e <function>session_regenerate_id</function> poderia causar um ataque DoS pessoal
|
|
por causa de cookies impossíveis de serem removidos e que foram configurados por atacantes. Quando isso acontecer,
|
|
o desenvolvedor pode solicitar aos usuários que removam os cookies e avisá-los que podem existir
|
|
problemas de segurança. Atacantes podem configurar cookies maliciosos via aplicações web vulneráveis,
|
|
extensões maliciosas para navegadores, dispositivos comprometidos fisicamente, etc.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Não interprete de forma equivocada o risco de DoS.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
é obrigatório para a segurança geral do ID de sessão! É recomendável que todos os sites
|
|
habilitem <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
|
|
</simpara>
|
|
<simpara>
|
|
DoS somente pode acontecer quando a conta está sob ataque. Uma vulnerabilidade de injeção
|
|
de JavaScript na aplicação representa a causa mais comum.
|
|
</simpara>
|
|
</warning>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-data-deletion">
|
|
<title>Remoção dos dados de sessão</title>
|
|
|
|
<para>
|
|
Os dados de sessões obsoletas devem ser inacessíveis e removidos.
|
|
O módulo de sessão atual não manipula isso muito bem.
|
|
</para>
|
|
|
|
<para>
|
|
É melhor remover os dados de sessões obsoletas o mais cedo possível.
|
|
Ainda assim, sessões ativas não devem ser removidas imediatamente.
|
|
Para preencher esses requisitos, o gerenciamento dos dados de sessões baseadas em timestamp
|
|
deve ser implementado pelo próprio desenvolvedor.
|
|
</para>
|
|
|
|
<para>
|
|
Configure e gerencie um timestamp de expiração na $_SESSION.
|
|
Bloqueie os acessos aos dados de sessões desatualizadas.
|
|
Quando um acesso aos dados de uma sessão obsoleta for detectado,
|
|
é aconselhável remover todos os status de autenticação das sessões dos usuários
|
|
e forçá-los a refazer a autenticação. O acesso aos dados de uma sessão obsoleta pode ser
|
|
um ataque. Para fazer isso, deve ser mantido um registro das sessões ativas por usuário.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
O acesso à uma sessão obsoleta pode ocorrer por causa de redes instáveis e/ou
|
|
acessos concorrentes ao website. O servidor tenta definir um novo ID de sessão
|
|
via cookie, mas o pacote que define o cookie (Set-Cookie) pode não ter chegado ao cliente por
|
|
perda de conexão. Uma conexão pode gerar um novo ID de sessão executando
|
|
<function>session_regenerate_id</function>, mas uma outra conexão
|
|
concorrente pode não ter pego ainda o novo ID de sessão.
|
|
Além disso, o acesso aos dados da sessão obsoleta deve ser bloqueado algum tempo depois.
|
|
Ou seja, o gerenciamento de sessão baseada em timestamp é necessário.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
Em poucas palavras, dados de sessão não devem ser destruídos com
|
|
<function>session_regenerate_id</function> ou <function>session_destroy</function>,
|
|
mas timestamps dem ser utilizados para controlar o acesso aos dados da sessão.
|
|
Deixe que <function>session_gc</function> remova os dados obsoletos do armazenamento de dados da sessão.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-locking">
|
|
<title>Sessão e Travamento dos dados</title>
|
|
|
|
<para>
|
|
Os dados de sessão são travados para evitar condição de corrida (data race) por padrão.
|
|
A trava é necessária para manter os dados consistentes entre as requisições.
|
|
</para>
|
|
|
|
<para>
|
|
Contudo, o travamento pode ser abusado por um atacante para realizar um ataque DoS.
|
|
Para diminuir os riscos de DoS por travamento de sessão, reduza o travamento.
|
|
Use sessões somente leitura quando a alteração dos dados não for necessária.
|
|
Use a opção 'read_and_close' com <function>session_start</function>.
|
|
<code>session_start(['read_and_close'=>1]);</code>
|
|
Feche a sessão assim que você terminar de alterar $_SESSION,
|
|
usando <function>session_commit</function>.
|
|
</para>
|
|
|
|
<para>
|
|
O módulo de sessão atual <emphasis>não</emphasis>
|
|
detecta modificações em $_SESSION enquanto a sessão está inativa.
|
|
É responsabilidade do desenvolvedor não modificar a variável $_SESSION quando
|
|
a sessão está inativa.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.active-sessions">
|
|
<title>Sessões ativas</title>
|
|
|
|
<para>
|
|
Os desenvolvedores devem manter um registro de sessões ativas por usuário.
|
|
E notificar o usuário sobre quantas sessões ativas, de qual IP (e área),
|
|
há quanto tempo a sessão está ativa, etc.
|
|
O PHP não mantém um registro dessas informações. É o desenvolvedor quem deve manter.
|
|
</para>
|
|
|
|
<para>
|
|
Existem inúmeras formas de implementação.
|
|
Pode ser configurado um banco de dados que mantém um registro
|
|
dos dados necessários e armazena as informações nele.
|
|
Como os dados de sessão são removidos pelo coletor de lixo, o desenvolvedor deve cuidar dos dados
|
|
removidos para manter a consistência do banco de dados das sessões ativas.
|
|
</para>
|
|
|
|
<para>
|
|
Uma das implementações mais simples é prefixar o ID de sessão com o ID do usuário e
|
|
armazenar as informações necessárias na $_SESSION.
|
|
Muitos bancos de dados têm bom desempenho para selecionar o prefixo de uma string.
|
|
Desemvolvedores PODEM usar <function>session_regenerate_id</function> e
|
|
<function>session_create_id</function> para isso.
|
|
</para>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Nunca utilize informações confidenciais como prefixo.
|
|
Se o ID do usuário for confidencial, considere a utilização
|
|
de <function>hash_hmac</function>.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<warning>
|
|
<simpara>
|
|
Habilitar <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
é obrigatório para esse setup. Certifique-se de que essa opção esteja habilitada, caso contrário
|
|
o banco de dados de sessões ativas pode ser comprometido.
|
|
</simpara>
|
|
</warning>
|
|
|
|
<para>
|
|
O gerenciamento de sessão baseada em timestamp é necessário para detectar acesso em sessões
|
|
obsoletas. Quando um acesso à uma sessão obsoleta é detectado, as flags de autenticação devem ser
|
|
removidas de todas as sessões ativas para esse usuário. Isso evita que atacantes
|
|
explorem sessões roubadas.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.session-and-autologin">
|
|
<title>Sessão e login automático</title>
|
|
|
|
<para>
|
|
Desenvolvedores não devem utilizar ID de sessão de longa vida para o login automático, pois isso
|
|
aumenta o risco de roubo da sessão. O login automático deve ser implementado
|
|
pelo desenvolvedor.
|
|
</para>
|
|
|
|
<para>
|
|
Use um hash seguro de uso único como chave para o login automático usando
|
|
<function>setcookie</function>. Use um hash seguro e mais forte que SHA-2,
|
|
como por exemplo, SHA-256 ou maior com dados randômicos provenientes de <function>random_bytes</function>
|
|
ou <filename>/dev/urandom</filename>.
|
|
</para>
|
|
|
|
<para>
|
|
Se o usuário não estiver autenticado, verifique se a chave de login automático é
|
|
válida ou não. Se a chave é válida, autentique o usuário e configure uma nova chave
|
|
"one-time hash" segura. Deve ser possível usar a chave de login automático apenas uma vez,
|
|
ou seja, nunca reutilize uma chave de login automático; ao invés disso, sempre gere uma nova chave.
|
|
</para>
|
|
|
|
<para>
|
|
A chave de login automático é uma chave de autenticação de longa vida, portanto essa chave deve estar
|
|
o mais protegida possível. Use os atributos de cookie path/httponly/secure
|
|
para protegê-la. Ou seja, nunca transmita a chave de login automático
|
|
a não ser que seja realmente necessário.
|
|
</para>
|
|
|
|
<para>
|
|
Desenvolvedores devem implementar funcionalidades que desabilitam login automático e removem
|
|
cookies de login automático desnecessários.
|
|
</para>
|
|
|
|
</sect2>
|
|
|
|
<sect2 xml:id="features.session.security.management.csrf">
|
|
<title>Ataques CSRF (Cross-Site Request Forgeries)</title>
|
|
|
|
<para>
|
|
Sessão e autenticação não protegem contra ataques CSRF. Os desenvolvedores
|
|
devem implementar proteções contra CSRF por conta própria.
|
|
</para>
|
|
|
|
<para>
|
|
<function>output_add_rewrite_var</function> pode ser usada para proteção contra
|
|
CSRF. Visite o manual para mais detalhes.
|
|
</para>
|
|
|
|
<note>
|
|
<simpara>
|
|
Versões do PHP anteriores à 7.2.0 utilizam o mesmo buffer de saída e as mesmas configurações INI
|
|
que o recurso trans sid. Portanto, o uso de <function>output_add_rewrite_var</function>
|
|
em versões do PHP anteriores à 7.2.0 não é recomendado.
|
|
</simpara>
|
|
</note>
|
|
|
|
<para>
|
|
A maioria dos frameworks para aplicações web tem suporte à proteção CSRF. Visite
|
|
o manual do framework de sua aplicação para mais detalhes.
|
|
</para>
|
|
|
|
<para>
|
|
A partir do PHP 7.3, o atributo SameSite para cookies de sessão pode ser utilizado.
|
|
É uma medida adicional que pode mitigar vulnerabilidades CSRF.
|
|
</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="session.security.ini">
|
|
<title>Protegendo as configurações INI relacionadas à sessão</title>
|
|
|
|
<para>
|
|
Ao proteger as configurações INI relacionadas à sessão, a segurança das sessões também aumenta.
|
|
Algumas configurações INI importantes não possuem recomendações. O desenvolvedor
|
|
é o responsável em garantir a segurança das configurações de sessão.
|
|
</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-lifetime">session.cookie_lifetime</link>=0
|
|
</para>
|
|
<para>
|
|
<literal>0</literal> tem um sentido especial. Ele diz para o navegador não armazenar cookies no
|
|
armazenamento permanente. Sendo assim, quando o navegador é encerrado, o cookie com o
|
|
ID de sessão é deletado imediatamente. Se o desenvolvedor configurar um valor diferente de "0", pode
|
|
permitir que outros usuários utilizem o ID de sessão. A maioria das aplicações devem
|
|
utilizar <literal>0</literal> para isto.
|
|
</para>
|
|
<para>
|
|
Se a funcionalidade de login automático é necessária,
|
|
o desenvolvedor deve implementá-la por conta própria e de forma segura.
|
|
Não utilize um ID de sessão de longa vida para isso.
|
|
Mais informações podem ser encontradas acima na seção sobre este assunto.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-cookies">session.use_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=On
|
|
</para>
|
|
<para>
|
|
Embora o cookie HTTP tenha alguns problemas,
|
|
ele é o modo preferido para gerenciar o ID de sessão.
|
|
Utilize apenas cookies para o gerenciamento do ID de sessão quando
|
|
possível. A maioria das aplicações devem utilizar cookie para o ID de sessão.
|
|
</para>
|
|
<para>
|
|
Se <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=Off,
|
|
o módulo de sessão usará valores para o ID de sessão definidos por
|
|
GET ou POST desde que o cookie de ID de sessão não tenha sido inicializado.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
|
</para>
|
|
<para>
|
|
Contudo, habilitar
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
é obrigatório para sessões seguras. Essa opção está desabilitada por padrão.
|
|
</para>
|
|
<para>
|
|
Essa opção evita que o módulo de sessão utilize um ID de sessão que não tenha sido inicializado.
|
|
Em outras palavras, o módulo de sessão aceita apenas ID de sessão válido
|
|
e que tenha sido gerado pelo módulo de sessão.
|
|
O módulo de sessão rejeita o ID caso ele tenha sido fornecido pelo usuário.
|
|
</para>
|
|
<para>
|
|
Por causa das especificações dos cookies, atacantes podem configurar cookies
|
|
de ID de sessão indeletáveis por causa de configurações locais ou
|
|
por injeção de JavaScript.
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> pode evitar que um ID de sessão
|
|
inicializado por um atacante seja utilizado.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Atacantes podem inicializar um ID de sessão utilizando os próprios computadores e depois configurá-lo
|
|
como o da vítima. No entanto, eles precisariam manter o ID de sessão ativo.
|
|
Também seria necessário alguns passos adicionais para executar um ataque nesse cenário.
|
|
Portanto, a opção
|
|
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
|
funciona como prevenção.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-httponly">session.cookie_httponly</link>=On
|
|
</para>
|
|
<para>
|
|
Proíbe o acesso ao cookie de sessão através do JavaScript. Essa configuração
|
|
evita o roubo de cookies por injeção de JavaScript.
|
|
</para>
|
|
<para>
|
|
É possível usar um ID de sessão como chave de proteção contra CSRF, mas isso não é recomendado.
|
|
Por exemplo, o código HTML pode ser salvo e enviado para outros usuários.
|
|
Os desenvolvedores não devem escrever o ID de sessão nas páginas, para evitar problemas de segurança.
|
|
Quase todas as aplicações devem utilizar o atributo httponly para o cookie do ID de sessão.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
O token de proteção contra CSRF deve ser renovado periodicamente, exatamente como o ID de sessão.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-secure">session.cookie_secure</link>=On
|
|
</para>
|
|
<para>
|
|
Permite o acesso ao cookie de ID de sessão apenas quando o protocolo é HTTPS. Se
|
|
seu website utiliza apenas HTTPS, então essa opção deve ser habilitada.
|
|
</para>
|
|
<para>
|
|
O uso de HSTS deve ser considerado em websites que utilizem apenas HTTPS.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Lax" ou
|
|
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Strict"
|
|
</para>
|
|
<para>
|
|
A partir do PHP 7.3 o atributo <literal>"SameSite"</literal> pode ser definido para o cookie de ID de sessão.
|
|
Este atributo é uma forma de se mitigar ataques CSRF (Cross Site Request Forgery).
|
|
</para>
|
|
<para>
|
|
A diferença entre Lax e Strict é a acessibilidade do cookie em
|
|
requisições que se original de outro domínio registrável empregando o método HTTP GET.
|
|
Cookies usando Lax serão acessíveis em uma requisição GET originada de
|
|
outro domínio registrável, enquanto que cookies que usam Strict não serão.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>=[choose smallest possible]
|
|
</para>
|
|
<para>
|
|
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>
|
|
é a configuração para remoção de ID de sessão obsoleta. Depender dessa configuração
|
|
<emphasis>não</emphasis> é recomendado. O gerenciamento do tempo de vida da sessão deve ser feito utilizando timestamp e
|
|
por contra própria.
|
|
</para>
|
|
<para>
|
|
É melhor que a coleta de lixo (garbage collection) da sessão seja feita pela função <function>session_gc</function>.
|
|
<function>session_gc</function> é recomendada ser executada pelos gerenciadores de
|
|
tarefas, como, por exemplo, cron em sistemas tipo Unix.
|
|
</para>
|
|
<para>
|
|
Por padrão, a coleta de lixo (GC) é executada por probabilidade.
|
|
Essa configuração <emphasis>não</emphasis> garante a remoção de
|
|
sessões antigas.
|
|
Embora o desenvolvedor não possa depender dessa configuração,
|
|
defini-la com o menor valor possível é recomendado.
|
|
Ajuste
|
|
<link linkend="ini.session.gc-probability">session.gc_probability</link>
|
|
e
|
|
<link linkend="ini.session.gc-divisor">session.gc_divisor</link> para
|
|
que as sessões obsoletas sejam deletadas na frequência apropriada.
|
|
Se a funcionalidade de login automático é necessária, o desenvolvedor deve
|
|
implementá-la por contra própria e de forma segura, veja acima para mais informação.
|
|
Nunca utilize ID de sessão de longa vida para isso.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Alguns módulos de manipuladores de armazenamento de sessão não utilizam essa configuração para
|
|
a expiração baseada em probabilidade, como, por exemplo, memcached e memcache.
|
|
Visite a documentação do manipulador de armazenamento de sessão para mais detalhes.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>=Off
|
|
</para>
|
|
<para>
|
|
O uso de gerenciamento transparente do ID de sessão não é proibido. Ele
|
|
pode ser utilizado quando necessário. Contudo, desabilitar o gerenciamento transparente
|
|
do ID de sessão melhora a segurança geral do ID de sessão, pois
|
|
remove a possibilidade de injeção e vazamento do ID de sessão.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
O ID de sessão pode ser exposto através de uma URL salva nos Favoritos do navegador, uma URL enviada por e-mail ou mesmo caso o código-fonte HTML seja salvo.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-tags">session.trans_sid_tags</link>=[tags limitadas]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Desenvolvedores não devem reescrever tags HTML sem necessidade. A configuração padrão
|
|
é suficiente para a maioria dos casos.
|
|
Versões anteriores do PHP utilizam a configuração
|
|
<link linkend="ini.url-rewriter.tags">url_rewriter.tags</link> para tal.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.trans-sid-hosts">session.trans_sid_hosts</link>=[hosts limitados]
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 >=) Essa configuração INI define uma lista de hosts que permitem a reescrita do recurso
|
|
trans sid. Nunca adicione hosts que não sejam confiáveis.
|
|
O módulo de sessão permite apenas o valor de <literal>$_SERVER['HTTP_HOST']</literal>
|
|
quando essa configuração está vazia.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.referer-check">session.referer_check</link>=[sua URL de origem]
|
|
</para>
|
|
<para>
|
|
Quando
|
|
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
|
|
estiver habilitada, o uso dessa opção é recomendado.
|
|
Ela reduz o risco de injeção do ID de sessão. Se seu site é
|
|
<literal>http://example.com/</literal>,
|
|
defina essa opção como <literal>http://example.com/</literal>.
|
|
Note que quando HTTPS é utilizado, o navegador não enviará o cabeçalho relacionado ao "referer".
|
|
O navegador também pode não enviar o "referer" dependendo da configuração.
|
|
Portanto, essa configuração não é uma medida de segurança confiável.
|
|
O uso desta configuração é recomendado.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.cache-limiter">session.cache_limiter</link>=nocache
|
|
</para>
|
|
<para>
|
|
Certifique-se de que o conteúdo HTTP não é armazenado em cache para sessões autenticadas.
|
|
Permita o armazenamento em cache apenas quando o conteúdo não é privado.
|
|
Caso contrário, o conteúdo pode ser exposto.
|
|
<literal>"private"</literal> pode ser usado se o conteúdo HTTP não
|
|
incluir dados sensíveis/confidenciais.
|
|
Note que <literal>"private"</literal> pode fazer com que dados privados
|
|
sejam armazenados em cache em clientes compartilhados.
|
|
<literal>"public"</literal> pode ser usado somente quando o conteúdo HTTP não
|
|
contém dados privados e ou confidenciais.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.hash-function">session.hash_function</link>="sha256"
|
|
</para>
|
|
<para>
|
|
(PHP 7.1.0 <) Funções de hash mais fortes também geram um ID de sessão mais
|
|
forte. Embora a colisão de hash é pouco provável até mesmo com MD5, desenvolvedores
|
|
devem usar SHA-2 ou funções de hash ainda mais fortes para essa tarefa. Os desenvolvedores podem
|
|
usar um hash mais forte como sha384 ou sha512. Certifique-se de informar um valor suficientemente
|
|
longo em <link linkend="ini.session.entropy-length">entropy</link> para
|
|
a função de hash usada.
|
|
</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>
|
|
<link linkend="ini.session.save-path">session.save_path</link>=[diretório não público]
|
|
</para>
|
|
<para>
|
|
Se for definido para um diretório público, como
|
|
<filename>/tmp</filename> (o padrão), outros usuários no
|
|
servidor podem ser capazes de sequestrar seções obtendo a lista de
|
|
arquivos nesse diretório.
|
|
</para>
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
</sect1>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|