← Todas as verificações
SegurançaSeveridade típica: Médio

Cache de respostas com sessão

Deteta respostas com cookie de sessão marcadas como cacheáveis, que uma CDN partilhada poderia servir a outro utilizador.

O que verifica

Este scanner revê as respostas do teu site que incluem uma cookie de sessão e verifica se estão marcadas como cacheáveis. Deteta quando uma página personalizada ou com dados de sessão podia ficar guardada numa cache partilhada, como um CDN ou um proxy intermédio.

Porque importa

Se uma resposta ligada à sessão de um utilizador for guardada numa cache partilhada, essa cache pode acabar por servi-la a uma pessoa completamente diferente. Isso significa que um visitante podia ver a conta, os dados ou a sessão de outro, uma fuga de informação séria.

Como se corrige

Garante que qualquer resposta com dados de sessão leva cabeçalhos que impedem a cache, como Cache-Control com private e no-store. Revê as definições do teu CDN ou proxy para que nunca guarde páginas associadas a uma cookie de sessão.

Como funciona esta verificação

O Scanaris olha para a resposta principal da tua página e verifica duas condições ao mesmo tempo. Primeira: a resposta estabelece pelo menos um cookie (Set-Cookie) cujo nome começa por sess, sid, auth, token, jwt, connect.sid, phpsessid ou asp.net, ou seja, um cookie que muito provavelmente identifica uma sessão. Segunda: a mesma resposta leva Cache-Control com a diretiva public. Só se ambas se cumprirem abre um achado de severidade média com o nome do cookie e o valor do cabeçalho. É deliberadamente estrito: um cookie de preferências com cache pública, ou um cookie de sessão sem public, não são marcados.

Porque importa

Cache-Control: public é uma instrução explícita a qualquer cache partilhada (uma CDN, um proxy inverso como o Varnish ou o nginx, o proxy de uma empresa ou operadora) de que essa resposta pode ser guardada e entregue a outros utilizadores. Se essa mesma resposta inclui um Set-Cookie de sessão, a cache pode guardar o cookie junto com o corpo e dá-lo ao visitante seguinte. Esse visitante entra com a sessão do anterior, sem palavra-passe, e vê os dados dele. É uma falha das que se descobrem quando um cliente escreve a dizer que "entrou na conta de outra pessoa". Aconteceu em bancos e em lojas grandes, sempre pela mesma combinação: conteúdo personalizado marcado como cacheável.

Porque acontece

Normalmente por uma regra de cache demasiado ampla: um add_header Cache-Control "public, max-age=3600" no nginx aplicado a todas as rotas, incluindo as que criam sessão; uma regra "Cache Everything" no Cloudflare; ou um routeRules com cabeçalhos de cache para '/**' numa app que estabelece cookies na página principal. A maioria das CDN recusa guardar respostas com Set-Cookie por defeito, e o nginx também, salvo que lhe digas para ignorar esse cabeçalho, mas um public explícito és tu a dizer-lhes que o façam.

Como corrigir

  • As respostas que criam ou renovam sessão levam Cache-Control: private, no-store. É o que fazem por defeito o express-session, o Laravel, o Django e o Rails; se vês public, foi uma camada posterior que o adicionou.
  • Separa as regras de cache por tipo de rota. public com max-age longo para os ficheiros estáticos com hash no nome (/_nuxt/, /_next/static/, /assets/); private ou no-store para o HTML que depende do utilizador. No nginx, usa blocos location distintos; no Nuxt e no Next.js, regras por rota em vez de uma global.
  • Não estabeleças o cookie de sessão em páginas públicas cacheáveis. Se a home não precisa de sessão, não a crie: cria o cookie ao iniciar sessão ou ao entrar no painel.
  • Se usas uma CDN com "Cache Everything" ou semelhante, adiciona uma regra para não fazer cache de respostas com Set-Cookie nem das rotas autenticadas. E adiciona Vary: Cookie como rede adicional, embora não substitua o anterior.

Confirma que está corrigido

curl -sI https://teudominio.com | grep -iE "^(set-cookie|cache-control|vary):"
curl -sI https://teudominio.com/dashboard | grep -iE "^(set-cookie|cache-control):"

Se houver Set-Cookie com nome de sessão, o Cache-Control dessa resposta deve ser private, no-store ou no-cache, nunca public. Faz o segundo pedido com e sem o teu cookie de sessão: a resposta autenticada nunca deve aparecer sem ele.

Perguntas frequentes

A minha CDN diz que não faz cache de respostas com cookies. Então é falso positivo?

Provavelmente a fuga não está a acontecer hoje, mas dependes de um comportamento por defeito que uma regra nova ou uma mudança de fornecedor podem desativar. O cabeçalho diz que é público; corrige o cabeçalho e deixa de depender da exceção.

E os cookies de analítica ou de consentimento?

Não são marcados: só contam os nomes que indicam sessão. Um cookie de consentimento numa página pública com cache é normal. Como devem estar configurados os cookies de sessão (Secure, HttpOnly, SameSite) vê-o cookies inseguros.

A minha sessão vai num token no localStorage, não em cookie.

Então esta verificação não se aplica, mas token no armazenamento sim: um token acessível a partir do JavaScript tem outros problemas.

Verifica-o no teu site

Analisa o teu site grátis e vê se esta e outras 44 verificações passam, com um fix prompt por cada problema.

Analisar o meu site grátis

Verificações relacionadas