Cookies: HttpOnly, Secure, SameSite — e o CSRF
Um cookie de sessão são três atributos e um problema. Vale a pena perceber os três, porque cada um fecha uma porta diferente.
Set-Cookie: sessao=abc123; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=6048001. HttpOnly — contra o XSS
O JavaScript da página não consegue ler o cookie. Se alguém conseguir injetar um script, não leva a sessão com ele. É uma linha, e é a diferença entre um incidente e uma conta comprometida.
2. Secure — contra a escuta
O cookie só viaja em HTTPS. Sem isto, basta uma ligação por engano em http:// — um redirecionamento antigo, um link de um email — para o cookie atravessar a rede em claro.
3. SameSite — contra o CSRF
Este exige explicar o ataque. Imagine que está autenticado no seu banco. Noutro separador, abre um site qualquer que tem isto escondido:
<form action="https://banco.pt/transferir" method="POST">
<input name="para" value="123" />
<input name="valor" value="500" />
</form>
<script>document.forms[0].submit()</script>O browser envia o pedido com os seus cookies, porque é assim que os cookies funcionam. O banco vê um pedido autenticado e obedece.
O SameSite resolve-o dizendo quando é que o cookie acompanha pedidos vindos de outro sítio:
Lax — acompanha navegações normais (clicar num link), não acompanha submissões de formulários de outro sítio. É a predefinição nos browsers atuais, e serve para quase tudo.
Strict — nunca acompanha. Mais seguro, e com um efeito colateral: quem chega de um link externo aterra como se não tivesse sessão.
None — acompanha sempre, e obriga a
Secure. Só para casos genuínos de terceiros.
4. E o token anti-CSRF ainda faz falta?
Com SameSite=Lax ou Strict, o essencial está coberto para browsers atuais. Mas o token continua a valer a pena onde a ação é irreversível — apagar uma conta, transferir dinheiro — porque não custa nada e não depende de o browser de quem visita ser recente.
E uma nota de arrumação: Path e Max-Age não são segurança, são higiene. Um cookie sem validade fica lá para sempre.