Segurança
Como verificar a segurança dos cookies: Secure, HttpOnly, SameSite e prefixos de cookie
Os cookies de sessão são as chaves das contas dos seus visitantes. Veja como cada atributo de cookie os protege, como inspecionar os seus próprios cookies e como configurá-los corretamente.
Nesta página
Quando alguém faz login no seu site, o servidor normalmente entrega ao navegador dessa pessoa um cookie de sessão. A partir daí, quem estiver de posse desse cookie é esse usuário. Os atributos do cookie determinam quando o navegador o envia, por quais conexões e se os scripts da página podem lê-lo. Acertar custa uma linha de configuração; errar pode transformar um bug pequeno em um sequestro de conta.
Os atributos que importam
Secure
Secure diz ao navegador para enviar o cookie somente por HTTPS. Sem ele, o cookie pode trafegar em uma requisição HTTP comum — por exemplo, quando alguém digita o seu domínio sem https://, antes de o redirecionamento acontecer —, e aí qualquer pessoa na mesma rede consegue lê-lo. Em um site HTTPS, todo cookie deve ser Secure.
HttpOnly
HttpOnly esconde o cookie do JavaScript (document.cookie). Se um invasor conseguir injetar um script na sua página, ele não poderá simplesmente ler um cookie de sessão e enviá-lo para outro lugar. Use-o em cookies de sessão e de autenticação. Os cookies que o seu próprio código de front-end precisa ler, como um token CSRF que alguns frameworks expõem de propósito ao JavaScript, não podem ser HttpOnly — e isso é esperado.
SameSite
SameSite controla se o cookie é enviado quando a requisição vem de outro site:
SameSite=Strict: enviado apenas em requisições que começam no seu próprio site. É o mais seguro, mas um visitante que segue um link de um e-mail para o seu site chega parecendo deslogado.SameSite=Lax: enviado em navegações de nível superior, como o clique em um link, mas não em envios de formulário, imagens ou frames entre sites. Um bom padrão para cookies de sessão.SameSite=None: enviado em qualquer contexto entre sites, necessário para widgets incorporados e alguns fluxos de login único (SSO). Precisa ser combinado comSecure, ou os navegadores rejeitam o cookie.
Os navegadores baseados em Chromium tratam um cookie sem o atributo SameSite como Lax, mas nem todo navegador se comporta assim; portanto, defina-o explicitamente.
Domain e Path
Se você omitir Domain, o cookie fica restrito ao host (host-only): enviado apenas ao host exato que o definiu. Definir Domain=example.com o compartilha com todos os subdomínios, inclusive aqueles esquecidos em outra hospedagem, que podem ser menos seguros. Só amplie o escopo quando você realmente precisar compartilhar um login entre subdomínios.
Expires e Max-Age
Sem Expires ou Max-Age, o cookie deveria durar apenas a sessão do navegador, embora navegadores que restauram sessões possam mantê-lo por mais tempo. Para logins persistentes, escolha uma duração compatível com o risco e garanta que o servidor também expire as sessões do lado dele.
Prefixos de cookie: __Host- e __Secure-
Os prefixos no nome do cookie fazem o navegador aplicar as regras por você. Um cookie cujo nome começa com __Secure- só é aceito se tiver o atributo Secure e tiver sido definido por HTTPS. Um cookie que começa com __Host- é mais rigoroso: precisa ser Secure, ser definido por HTTPS, ter Path=/ e não ter o atributo Domain. Isso o prende a um único host, de modo que um subdomínio comprometido ou descuidado não consegue sobrescrevê-lo.
Para um cookie de sessão que não precisa ser compartilhado entre subdomínios, __Host- é a opção mais forte disponível: Set-Cookie: __Host-session=…; Secure; HttpOnly; SameSite=Lax; Path=/.
Como verificar os seus cookies
- No navegador. Abra as ferramentas de desenvolvedor, vá até Application (Chrome, Edge) ou Storage (Firefox), depois Cookies, e selecione o seu site. A tabela mostra as colunas Domain, Path, Expires, HttpOnly, Secure e SameSite de cada cookie.
- Na resposta bruta. Na aba Network (Rede), clique na requisição do documento e leia os cabeçalhos de resposta
Set-Cookie. Isso mostra exatamente o que o servidor enviou, inclusive atributos que o navegador possa ter rejeitado. - Depois do login. Muitos sites só definem os cookies importantes após o login ou quando um carrinho é criado; então verifique de novo nessas páginas.
- Com um verificador. O verificador de segurança gratuito do Rudra lê os cabeçalhos
Set-Cookieda resposta da própria página e aponta cookies semSecureem HTTPS, cookies com cara de sessão semHttpOnly,SameSite=NonesemSecure, cookies semSameSitee cookies com escopo no domínio pai.
Vale conhecer dois limites da verificação automática. Ela decide se um cookie tem "cara de sessão" pelo nome (nomes que contêm trechos como sess, sid, token ou auth); por isso, reporta esses apontamentos com confiança média: confirme o que o cookie realmente guarda. E ela só enxerga os cookies definidos por aquela única resposta — não os definidos depois por JavaScript, por outras páginas, após o login ou por terceiros. Os valores dos cookies nunca são lidos nem armazenados.
Verifique os atributos dos seus cookies
Informe uma página e o Rudra mostra os atributos Secure, HttpOnly e SameSite dos cookies que ela define, apenas pelo nome, junto com a sua configuração de HTTPS e de cabeçalhos.
Como definir os atributos de cookie nas plataformas mais comuns
- Sessões PHP: no
php.ini, definasession.cookie_secure = 1,session.cookie_httponly = 1esession.cookie_samesite = "Lax"(PHP 7.3 ou superior), ou passe as mesmas opções parasession_set_cookie_params(). - Django:
SESSION_COOKIE_SECURE = TrueeCSRF_COOKIE_SECURE = True.SESSION_COOKIE_HTTPONLYeSESSION_COOKIE_SAMESITE = "Lax"já são os padrões. - Express (Node.js):
res.cookie("sid", value, { secure: true, httpOnly: true, sameSite: "lax" }), ou as opçõescookiedoexpress-session. Atrás de um proxy, ativetrust proxypara que o Express saiba que a conexão é HTTPS. - WordPress: os cookies de login do núcleo são
HttpOnlye marcados comoSecurequando o site roda em HTTPS. Os cookies de plugins variam; confira-os nas ferramentas de desenvolvedor e fale com os autores do plugin se estiverem sem os atributos. - Proxy reverso como último recurso: a diretiva
proxy_cookie_flagsdo nginx (1.19.3 ou superior) pode adicionarsecure,httponlyesamesiteaos cookies de uma aplicação que você não pode alterar.
Erros comuns
- Marcar os cookies como
Secureem produção, mas testar só por HTTP localmente e depois desativar o atributo "temporariamente". - Definir
SameSite=NonesemSecure, o que faz os navegadores descartarem o cookie e um login ou conteúdo incorporado parar de funcionar. - Dar aos cookies de sessão o escopo do domínio pai "por via das dúvidas".
- Guardar tokens de sessão no
localStorage, onde qualquer script injetado consegue lê-los — cookiesHttpOnlysão mais seguros. - Colocar dados pessoais nos valores dos cookies. Cookies devem guardar identificadores, não informações.
Os cookies são só uma parte do quadro. Para cabeçalhos, HTTPS e os limites dos testes passivos, leia como verificar a segurança de um site.
Perguntas frequentes
Todo cookie deve ser HttpOnly?
Todo cookie que o JavaScript não precisa ler, sim. Cookies de sessão e de autenticação devem ser sempre HttpOnly. Cookies de preferências ou tokens que o seu código de front-end lê deliberadamente não podem ser, e não há problema nisso.
SameSite=Lax é suficiente para evitar CSRF?
Ele bloqueia os envios de formulário entre sites mais comuns, mas não é uma defesa completa por si só: subdomínios do mesmo site e requisições GET de nível superior ainda podem levar o cookie. Mantenha os tokens CSRF nas requisições que alteram estado e nunca altere dados com GET.
Por que meu cookie desaparece quando defino SameSite=None?
Os navegadores rejeitam cookies SameSite=None que não estejam também marcados como Secure. Adicione Secure e sirva o site por HTTPS.
O Rudra lê os valores dos meus cookies?
Não. O verificador de segurança registra apenas os nomes dos cookies e seus atributos. Valores, tokens e qualquer outra coisa dentro de um cookie nunca são lidos, armazenados nem exibidos.