Secure, HttpOnly e SameSite: corrija os atributos dos cookies
Resposta curta: cookies de sessão e de login devem ter Secure (enviados só por HTTPS), HttpOnly (o JavaScript não consegue ler, o que limita o estrago de um XSS) e SameSite=Lax ou Strict (não são enviados na maioria das requisições entre sites, o que ajuda contra CSRF). Defina-os onde o cookie é criado, ou adicione-os no servidor web como alternativa.
O código e a configuração ficam em inglês.
Veja o que o seu site envia
curl -sI https://yourdomain.com | grep -i '^set-cookie'Sessões do PHP
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = "Lax"setcookie('name', $value, [
'expires' => time() + 3600,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);WordPress
Os cookies de login do WordPress já são HttpOnly. Garanta que o painel funcione só em HTTPS para que eles também sejam Secure:
define( 'FORCE_SSL_ADMIN', true );Os cookies criados por plugins dependem de cada plugin. Se faltar atributo em algum, procure uma atualização ou use a alternativa no servidor mostrada abaixo.
nginx (como proxy reverso)
proxy_cookie_flags ~ secure httponly samesite=lax;Apache
Header edit Set-Cookie "^((?!.*;\s*Secure).*)$" "$1; Secure"
Header edit Set-Cookie "^((?!.*;\s*HttpOnly).*)$" "$1; HttpOnly"
Header edit Set-Cookie "^((?!.*;\s*SameSite).*)$" "$1; SameSite=Lax"Se os cookies vêm de um backend atrás de proxy (por exemplo, PHP-FPM atrás de ProxyPass) e nada muda, use Header always edit no lugar.
Não quebre nada
- Cookies que o seu próprio JavaScript precisa ler (alguns banners de consentimento, testes A/B) não podem ser HttpOnly.
SameSite=Noneé necessário para cookies usados dentro de iframes de terceiros, e exigeSecure.SameSite=Strictpode desconectar usuários que chegam por um link em um e-mail.Laxé o padrão mais seguro.
Perguntas frequentes
Cookies de análise precisam desses atributos?
Secure, sim, em um site HTTPS. HttpOnly só se nenhum script precisar lê-los, o que raramente acontece com ferramentas de análise.
SameSite=Lax é suficiente contra CSRF?
Ele bloqueia a maioria dos envios de formulário entre sites, mas formulários que alteram dados ainda devem usar tokens CSRF.
Por que um scanner ainda aponta um atributo faltando depois da correção?
Muitas vezes um cache de páginas ou uma CDN está servindo a resposta antiga, ou um plugin define o próprio cookie. Limpe o cache e confira as linhas Set-Cookie de novo.