privacy

Atributos de cookies seguros

O MetricSpot inspeciona cabeçalhos Set-Cookie por Secure, HttpOnly e SameSite. Faltar qualquer um aumenta a superfície de ataque para roubo de cookies e CSRF.

O que esta verificação faz

Lê todos os cabeçalhos de resposta Set-Cookie e verifica três flags:

  • Secure — cookie só enviado por HTTPS.
  • HttpOnly — cookie não legível a partir de JavaScript (bloqueia roubo via XSS).
  • SameSite=Lax|Strict|None — comportamento em pedidos entre sites (bloqueia CSRF).

Passa quando cada cookie que carrega estado de autenticação ou sessão tem as três.

Porque é importante

Os cookies guardam as chaves das sessões dos teus utilizadores. Um cookie sem estas flags está a uma vulnerabilidade XSS ou a um Wi-Fi hostil de distância da apropriação da conta:

  • Sem Secure → o cookie viaja em HTTP simples no primeiro pedido antes do HSTS entrar em ação. Sniffável no Wi-Fi do café.
  • Sem HttpOnly → qualquer script injetado (XSS, dependência npm maliciosa, anúncio hostil) consegue ler o cookie via document.cookie e exfiltrá-lo.
  • Sem SameSite → cross-site request forgery (CSRF). Uma página maliciosa pode submeter formulários ou despoletar pedidos em nome do teu utilizador autenticado.

Os navegadores têm vindo a apertar os valores por omissão: o Chrome traz hoje SameSite=Lax por defeito, mas código legado que define cookies explicitamente sem flags continua a vazar.

Como corrigir

Define todos os cookies de sessão/autenticação com as três flags.

Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=86400

Express / Node.js:

res.cookie("session", token, {
  httpOnly: true,
  secure: true,
  sameSite: "lax",
  maxAge: 86400 * 1000,
  path: "/",
});

Next.js (App Router com cookies()):

import { cookies } from "next/headers";

cookies().set({
  name: "session",
  value: token,
  httpOnly: true,
  secure: true,
  sameSite: "lax",
  path: "/",
  maxAge: 86400,
});

Bun.serve():

return new Response("ok", {
  headers: {
    "Set-Cookie": `session=${token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400`,
  },
});

Django:

# settings.py
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
CSRF_COOKIE_SAMESITE = "Lax"

Rails:

# config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store,
  key: "_app_session",
  secure: Rails.env.production?,
  httponly: true,
  same_site: :lax

PHP / WordPress: em wp-config.php ou antes de qualquer output:

ini_set('session.cookie_secure', '1');
ini_set('session.cookie_httponly', '1');
ini_set('session.cookie_samesite', 'Lax');

Qual valor SameSite?

  • Strict — cookie nunca enviado em pedidos entre sites. Proteção máxima, mas quebra o caso em que utilizadores seguem uma ligação para o teu site e chegam desautenticados. Bom para fluxos críticos (admin, banca).
  • Lax (padrão) — cookie enviado em navegações de topo (clicar numa ligação) mas não em POSTs cross-site, iframes ou pedidos de imagem. O bom padrão para a maioria dos sites.
  • None — cookie enviado em todos os pedidos cross-site. Requer Secure. Usa apenas quando precisas genuinamente de contexto de terceiros (widgets embebidos, fornecedores de identidade).

Prefixos no nome do cookie acrescentam uma segunda camada de imposição:

  • __Secure- — o navegador recusa-se a definir este cookie a menos que Secure também esteja presente.
  • __Host- — o navegador recusa a menos que Secure, Path=/ e sem atributo Domain.
Set-Cookie: __Host-session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax

Emparelha esta regra com HTTPS, ativar HSTS e a referrer policy para uma linha de base completa de segurança no transporte.

Perguntas frequentes

O HttpOnly vai quebrar o meu código no cliente?

Apenas se leres o cookie a partir de JavaScript. Para cookies de sessão/autenticação, não deves — o cookie deve ser opaco para o cliente e usado só pelo servidor. Se guardas dados que o JS precisa de ler, isso é outra categoria de cookie (preferências, estado de UI) e HttpOnly não se aplica.

E cookies de consentimento e analytics?

Os cookies de consentimento e analytics muitas vezes precisam genuinamente de ser legíveis por JavaScript. Define Secure e SameSite=Lax, mas dispensa o HttpOnly. A verificação do MetricSpot tolera isto — só avisa quando um cookie de sessão não tem as flags.

Isto afeta a conformidade com o RGPD diretamente?

Não no lado do consentimento/base legal, mas sim no lado da segurança. O Artigo 32 do RGPD exige “medidas técnicas apropriadas” — flags de cookie em falta são rotineiramente citadas em decisões das autoridades de supervisão como falha de segurança. Emparelha com um banner de consentimento de cookies e uma política de privacidade para a camada legal.

Fontes

Última atualização 2026-05-11