Situação atual: PHP2Shell. Duas vulnerabilidades críticas do PHP (CVSS 9,2) permitem executar código malicioso sem autenticação. Patches disponíveis desde 21/10/2026.O que fazer agora →

Sessões e cookies em PHP

As sessões transformam o HTTP, que não guarda estado, numa autenticação que se mantém ao longo de várias páginas. Aqui fica como o PHP o resolve, que valores por defeito valem e o que o session.upload_progress tem que ver com o PHP2Shell.

Atualizado em 5 min de leituraConhecimento PHP

Em resumo: O HTTP não memoriza nada entre dois pedidos. Uma sessão PHP resolve isso: o PHP atribui um ID de sessão aleatório, envia-o ao navegador como cookie e guarda os dados correspondentes no servidor, por defeito como ficheiro. A cada pedido seguinte, o session_start() volta a ler os dados com base no ID. À sessão PHP pertence também a função session.upload_progress, que o php.net recomenda desativar temporariamente do lado do servidor por causa do PHP2Shell.

Porque é que as aplicações web precisam de sessões

Cada pedido a um servidor web é independente. Sem um mecanismo adicional, uma loja não saberia, ao clicar em «Carrinho», quem acabou de colocar algo nele, e uma área de administração teria de pedir a palavra-passe a cada clique. As sessões ligam pedidos isolados numa sessão de utilização.

Para quem decide, isto significa: depois do login, o ID de sessão vale tanto como o nome de utilizador e a palavra-passe juntos. Para administradores, significa: onde e como estão os dados de sessão é uma questão de segurança, sobretudo em servidores com vários sites.

O que acontece no session_start()

O procedimento é o mesmo a cada pedido e pode descrever-se em cinco passos:

  1. O navegador envia o cookie com o nome da sessão, por defeito PHPSESSID.
  2. O session_start() lê o ID e passa-o ao handler de armazenamento, por defeito files.
  3. O handler carrega os dados guardados, o PHP reconverte-os com o serialize_handler e preenche $_SESSION.
  4. O script lê e altera $_SESSION como um array normal.
  5. No fim do pedido, o PHP volta a escrever os dados. Com session.lazy_write (por defeito: ligado), só se tiverem sido alterados.
<?php
session_start();

$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];

Se ainda não existe sessão, o PHP gera um novo ID e define o cookie. Com session.use_strict_mode ativo, o PHP rejeita IDs desconhecidos impostos pelo navegador e gera um novo. O manual do PHP considera esta definição obrigatória para a segurança básica.

Valores por defeito que convém conhecer

Os valores seguintes valem, segundo o manual do PHP, quando nada mais está configurado. Muitas distribuições e alojadores definem valores próprios, por isso conta sempre a configuração realmente efetiva.

Definição Por defeito Significado
session.save_handler files local de armazenamento dos dados, também possível Redis ou base de dados
session.name PHPSESSID nome do cookie
session.serialize_handler php formato dos dados guardados
session.use_strict_mode 0 IDs desconhecidos são aceites
session.use_only_cookies 1 sem ID de sessão no endereço
session.cookie_httponly 0 o JavaScript pode ler o cookie
session.cookie_secure 0 cookie também por HTTP não cifrado
session.cookie_samesite vazio sem atributo SameSite
session.gc_maxlifetime 1440 segundos até à possível limpeza
session.gc_probability / gc_divisor 1 / 100 limpeza em cerca de um em cada cem arranques
session.upload_progress.enabled 1 o progresso do upload é escrito na sessão

Os valores de cookie_httponly, cookie_secure e use_strict_mode não vêm, portanto, de fábrica orientados para a segurança. Como os definir corretamente descreve-o o guia Proteger sessões em PHP. As definições session.sid_length e session.sid_bits_per_character estão marcadas como obsoletas desde o PHP 8.4.0.

Definir cookies diretamente

Além do cookie de sessão, uma aplicação pode definir cookies próprios. Desde o PHP 7.3.0, o setcookie() aceita para isso um array de opções, incluindo samesite. Desde o PHP 8.5.0 existe ainda a opção partitioned.

<?php
setcookie('sprache', 'de', [
    'expires'  => time() + 60 * 60 * 24 * 30,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);

Segundo o manual, com samesite igual a None também secure tem de estar definido, caso contrário o navegador bloqueia o cookie. Os cookies são dados do navegador: o seu conteúdo regressa no pedido seguinte através de $_COOKIE e tem de ser verificado como qualquer outra entrada. Mais sobre isto na página Superglobals.

session.upload_progress: indicador de progresso para uploads

O PHP pode escrever na sessão o progresso durante o upload de um ficheiro. Para isso, o formulário envia um campo oculto com o nome de session.upload_progress.name, por defeito PHP_SESSION_UPLOAD_PROGRESS. O PHP guarda então os dados em $_SESSION sob uma chave com o prefixo upload_progress_, com indicações como hora de início, tamanho total e bytes já processados.

Importante para a compreensão: segundo o manual, o PHP escreve estas informações na sessão antes de qualquer script ser executado. A função trabalha, portanto, durante o processamento do pedido, antes do código da aplicação. As suas definições são do tipo INI_PERDIR e não podem ser alteradas em tempo de execução.

Sessões e PHP2Shell: a medida transitória

Como uma das medidas transitórias contra as vulnerabilidades do PHP2Shell, o php.net indica definir session.upload_progress.enabled=0 no php.ini, no pool FPM ou na configuração do servidor e reiniciar depois todos os workers, expressamente não através de ini_set() nem de .user.ini. A 23/10/2026 foi acrescentada a indicação sobre o CVE-2026-115560, com o mesmo remédio até à próxima versão regular de correção de erros.

; Pool FPM do site, depois reiniciar todos os workers
php_admin_flag[session.upload_progress.enabled] = off

Segundo relatos especializados, esta definição por si só não fecha ambas as vulnerabilidades. A atualização para PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35 continua a ser obrigatória. Se a sua aplicação utiliza sequer o progresso do upload e como definir a configuração de forma duradoura descreve-o o artigo Desativar o session.upload_progress.

Como ajuda concretamente a PHP SOS?

  • Lemos as definições de sessão realmente efetivas por site, não apenas os valores da linha de comandos.
  • Definimos as medidas transitórias do PHP2Shell por pool, reiniciamos todos os workers e verificamos o resultado.
  • Separamos os locais de armazenamento de sessões e os utilizadores dos pools entre sites, no âmbito do reforço de servidores.
  • Depois de um incidente, invalidamos todas as sessões existentes, para que IDs de sessão roubados deixem de valer.

Perguntas frequentes

Qual é a diferença entre cookie e sessão?

Um cookie é um pequeno registo que o navegador guarda e envia a cada pedido. Uma sessão guarda os dados propriamente ditos no servidor; no cookie consta apenas um identificador aleatório, o ID de sessão.

Quanto tempo vive uma sessão PHP?

O cookie de sessão vale, por defeito, até o navegador ser fechado. Os dados no servidor podem ser limpos após session.gc_maxlifetime, por defeito 1440 segundos sem acesso. Quando isso acontece realmente depende da lógica de limpeza do sistema.

O que faz o session.upload_progress?

A função escreve na sessão o progresso durante o upload de um ficheiro, para que um segundo pedido o possa mostrar. Está ativa por defeito. Por causa do PHP2Shell, o php.net recomenda desativá-la temporariamente do lado do servidor.

Basta desativar o session.upload_progress com ini_set()?

Não. Segundo o manual, a definição nem sequer pode ser alterada em tempo de execução, e o php.net indica expressamente o php.ini, o pool FPM ou a configuração do servidor como locais corretos, não o ini_set() nem o .user.ini. Depois, reiniciar todos os workers.

Fontes

Contacto imediato

Cada hora conta. Escreva-nos agora.

Descreva brevemente o sistema, a versão do PHP e o que observou. Entramos em contacto consigo, esclarecemos a situação e trabalhamos remotamente até o incidente estar concluído e documentado.

Ajuda imediata