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

Scanner de cookies inseguros

Deteta cookies sem os atributos Secure, HttpOnly ou SameSite que os protegem contra roubo e CSRF.

O que verifica

Este scanner analisa as cookies que o teu site entrega ao navegador e verifica se lhes faltam os atributos Secure, HttpOnly ou SameSite. Estes atributos limitam como e quando cada cookie pode ser usada. Só olha para as marcas de proteção, não para o conteúdo da cookie.

Porque importa

Uma cookie de sessão sem estes atributos pode ser roubada por scripts maliciosos ou viajar sem cifra, permitindo que alguém se faça passar pelos teus utilizadores. Também facilita ataques CSRF em que um terceiro age em nome do utilizador. Na prática, isto pode significar o sequestro completo da conta.

Como se corrige

Ao criar as cookies, marca Secure para que só viajem por HTTPS, HttpOnly para que o JavaScript não as possa ler e SameSite (Lax ou Strict) para limitar o uso entre sites. A maioria das frameworks e bibliotecas de sessão têm estas opções na sua configuração. Presta especial atenção à cookie de login ou de sessão.

Como funciona esta verificação

O Scanaris lê os cabeçalhos Set-Cookie que o teu servidor envia ao carregar a página principal e revê os atributos de cada cookie. Verifica três coisas: que leva Secure (só se exige se o site for por HTTPS), que leva HttpOnly e que declara SameSite. Se o nome do cookie sugerir sessão ou autenticação (session, auth, token, sid e semelhantes), o achado é de severidade média; se não, baixa. Há um caso especial com severidade média própria: SameSite=None sem Secure, que os navegadores modernos rejeitam diretamente, com o que o cookie não funciona e além disso denuncia uma configuração pensada para uso entre sites. Só se veem os cookies enviados nessa primeira resposta; os que se criam depois do login confirmam-se melhor com o comando mais abaixo ou com a análise autenticada.

O que significa cada atributo

  • Secure: o cookie só viaja por HTTPS. Sem ele, um pedido por HTTP (um link antigo, uma rede pública) envia-o em claro e qualquer pessoa na rede o lê.
  • HttpOnly: o JavaScript não o consegue ler. É a diferença entre um XSS roubar a sessão ou não conseguir.
  • SameSite: quando é enviado a partir de outro site. Lax envia-o em navegações normais mas não em pedidos iniciados por outro site; Strict nunca a partir de fora; None sempre, e exige Secure. É a defesa principal contra CSRF.

O que um atacante faz com um cookie de sessão sem estes atributos

Sem HttpOnly, qualquer script injetado faz document.cookie, envia o valor para o seu servidor e entra com a tua sessão. Sem SameSite, uma página alheia pode submeter um formulário ao teu site com o cookie anexado e fazer uma compra ou mudar um email em nome do utilizador. Sem Secure, basta que o utilizador abra um link http:// para o teu domínio numa rede partilhada. Nos três casos o resultado é o mesmo: alguém age como o teu utilizador.

Como corrigir consoante a tua framework

// Express com express-session
app.use(session({
  cookie: { secure: true, httpOnly: true, sameSite: 'lax' }
}));

// Next.js (Route Handler ou Server Action)
cookies().set('session', value, { httpOnly: true, secure: true, sameSite: 'lax', path: '/' });

// Nuxt (server/api)
setCookie(event, 'session', value, { httpOnly: true, secure: true, sameSite: 'lax', path: '/' });

Com Supabase numa app com servidor, a biblioteca @supabase/ssr guarda a sessão em cookies com estes atributos; numa SPA pura a sessão vai para o localStorage, que é o que mede o check de tokens no storage. Em Django, Rails ou Laravel os atributos configuram-se nas definições de sessão e vêm razoáveis por defeito; confirma que ninguém os baixou para "resolver" um problema de desenvolvimento.

Confirma que está corrigido

curl -sI https://oteudominio.com | grep -i "set-cookie"
curl -sI -X POST https://oteudominio.com/api/login -d "..." | grep -i "set-cookie"

Cada cookie de sessão deve mostrar Secure; HttpOnly; SameSite=Lax (ou Strict). Se o teu login for um formulário, vê a resposta nas ferramentas do navegador, separador Rede, cabeçalhos de resposta.

Perguntas frequentes

O meu cookie é criado pelo JavaScript (analítica, preferências). Não pode ser HttpOnly.

Correto, e não faz mal: esses cookies não dão acesso a nada. O check marca-o com severidade baixa pelo atributo em falta; o que importa é que os de sessão o tenham.

Preciso de SameSite=None porque a minha app corre dentro de um iframe noutro domínio.

Então é legítimo, sempre com Secure. Garante que as restantes defesas contra CSRF (tokens nos formulários, verificação do Origin) estão ativas, porque o SameSite já não te protege.

Lax ou Strict?

Lax para a maioria: mantém a sessão quando o utilizador chega a partir de um link externo. Strict se o cookie dá acesso a algo muito sensível e aceitas que o utilizador tenha de voltar a entrar quando chega de fora.

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

Do blog

Verificações relacionadas