Saiba como definir cookies primários para garantir a segurança, a compatibilidade com vários navegadores e minimizar as chances de falhas quando os cookies de terceiros forem desativados.
Os cookies podem ser primários ou de terceiros em relação ao contexto do usuário, dependendo do site que ele está acessando no momento. Se o domínio e o esquema registráveis do cookie corresponderem à página de nível superior atual, ou seja, o que é exibido na barra de endereço do navegador, o cookie será considerado do mesmo site que a página e geralmente será chamado de cookie primário.
Os cookies de domínios diferentes do site atual geralmente são chamados de cookies de terceiros.
A receita de cookie primário ideal
Se o cookie que você está definindo não for usado em vários sites, por exemplo, se ele for usado para gerenciar sessões no seu site e nunca for usado em um iframe entre sites, esse cookie será sempre usado em um contexto primário.
Por padrão, os cookies podem ser compartilhados entre sites, acessados por JavaScript e enviados por conexões HTTP, o que traz alguns riscos de privacidade e segurança. Embora o trabalho para melhorar o comportamento padrão continue, com o Sandbox de privacidade e outras propostas, como cookies vinculados à origem, já é possível fazer muito mais definindo outros atributos nos cookies.
A configuração a seguir é uma prática recomendada que garante a segurança e a compatibilidade entre navegadores para a maioria dos cookies próprios. Ele vai fornecer uma base segura, que você pode ajustar para abrir permissões apenas quando necessário. Este artigo também aborda variações de receita para alguns casos de uso específicos.
A receita
Set-Cookie:
__Host-cookie-name=cookie-value;
Secure;
Path=/;
HttpOnly;
Max-Age=7776000;
SameSite=Lax;
Host
é um prefixo opcional que torna alguns atributos obrigatórios e proíbe outros:
Secure
precisa estar presenteDomain
precisa ser omitidoPath
precisa ser/
Com Host
adicionado, você pode confiar no navegador para verificar se esses atributos estão definidos de acordo com as regras __Host
e rejeitar o cookie caso contrário.
O Secure
protege os cookies contra roubo em redes não seguras, porque só permite o envio de cookies por conexões HTTPS. Se você não migrou seu site para HTTPS, faça isso o mais rápido possível.
O atributo Domain
especifica quais hosts podem receber um cookie. Omitir essa restrição limita o cookie ao host do documento atual, excluindo subdomínios: o cookie para example.com
será enviado em todas as solicitações para example.com
, mas não em solicitações para images.example.com
. Se você tiver apps diferentes em subdomínios diferentes, isso reduzirá o risco de um domínio comprometido permitir a entrada em outros.
Path
indica o caminho que precisa existir no URL solicitado para que o navegador envie o cabeçalho Cookie
. A definição de Path=/
significa que o cookie é enviado para todos os caminhos de URL nesse domínio. A combinação de Domain
e Path=/
faz com que o cookie seja vinculado à origem o mais próximo possível, para que ele se comporte de maneira semelhante a outros armazenamentos do lado do cliente, como LocalStorage
. Não há confusão de que example.com/a
possa receber valores diferentes de example.com/b
.
O atributo HttpOnly
adiciona proteção contra scripts maliciosos de terceiros nos seus sites, restringindo o acesso ao JavaScript. Ele permite que um cookie seja enviado apenas em cabeçalhos de solicitação e os torna indisponíveis para o JavaScript usando document.cookie
.
O Max-Age
limita a vida útil de um cookie, já que as sessões do navegador podem durar muito tempo, e você não quer que cookies desatualizados fiquem por aí para sempre. É bom para cookies de curto prazo, como sessões de usuários ou até mesmo mais curtos, como tokens para envio de formulários. Max-Age
é definido em segundos e, no exemplo anterior, é definido como 7776000 segundos, ou seja, 90 dias. Esse é um padrão razoável, que pode ser alterado de acordo com o caso de uso.
SameSite=Lax
restringe o cookie para que ele seja enviado apenas em solicitações do mesmo site. Ou seja, quando a solicitação corresponde ao contexto de navegação atual, o site de nível superior que o usuário está visitando e que aparece na barra de localização. SameSite=Lax
é o padrão em navegadores modernos, mas é recomendável especificar esse valor para garantir a compatibilidade entre navegadores que podem ter padrões diferentes. Ao marcar explicitamente o cookie como somente para o mesmo site, você o restringe aos seus contextos próprios, e não precisa fazer mudanças nele quando os cookies de terceiros forem removidos.
Para saber mais sobre os diferentes atributos de cookies, consulte a documentação do Set-Cookie
no MDN.
Receita de cookies primários para sites com subdomínios
Se você tiver um site com subdomínios e quiser ter uma sessão em todos eles, o prefixo Host
pode ser muito restritivo. Por exemplo, news.site
pode ter subdomínios para temas, como finance.news.site
e sport.news.site
, e você quer uma sessão de usuário em todos eles. Nesse caso, use o prefixo __Secure
em vez de __Host
e especifique Domain
.
A receita
Set-Cookie:
__Secure-cookie-name=cookie-value;
Secure;
Domain=news.site;
Path=/;
HttpOnly;
Max-Age=7776000;
SameSite=Lax;
Secure
é um prefixo opcional que define menos requisitos do que Host
: ele exige apenas que o cookie seja definido com o atributo Secure
.
Como restringir o acesso a cookies primários em solicitações iniciadas em sites de terceiros
Embora os cookies SameSite=Lax
não sejam enviados em subsolicitações entre sites (por exemplo, ao carregar imagens incorporadas ou iframes em um site de terceiros), eles são enviados quando um usuário navega para o site de origem (por exemplo, ao clicar em um link de outro site).
É possível restringir ainda mais o acesso a cookies e impedir o envio deles com solicitações iniciadas em sites de terceiros com SameSite=Strict
. Isso é útil quando você tem cookies relacionados a uma funcionalidade que sempre está por trás de uma navegação inicial, como alterar uma senha ou fazer uma compra.
A receita
Set-Cookie:
__Host-cookie-name=cookie-value;
Secure;
Path=/;
HttpOnly;
Max-Age=7776000;
SameSite=Strict;