Receitas de cookies primários

Saiba como definir cookies primários para garantir a segurança, a compatibilidade entre navegadores e minimizar as chances de falha 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 em que ele está no momento. Se o esquema e o domínio registráveis do cookie corresponderem à página de nível superior atual, ou seja, ao 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.

Se o cookie que você estiver configurando não for usado em outros 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 sempre será usado em um contexto próprio.

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. Há um trabalho em andamento para melhorar o comportamento padrão, mas com o Sandbox de privacidade e outras propostas, como cookies vinculados à origem, há muito que você pode fazer hoje ao definir mais 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 primários. Ele fornecerá uma base segura, que poderá ser ajustada para liberar permissões somente quando necessário. Este artigo também aborda variações de receitas para alguns casos de uso específicos.

A receita

Set-Cookie:
__Host-cookie-name=cookie-value;
Secure;
Path=/;
HttpOnly;
Max-Age=7776000;
SameSite=Lax;
Detalhes

Host é um prefixo opcional que torna alguns atributos obrigatórios e proíbe outros:

  • Secure precisa estar presente
  • Domain precisa ser omitido
  • Path precisa ser /

Com a adição de Host, o navegador pode verificar se esses atributos estão definidos de acordo com as regras do __Host e, caso contrário, rejeitar o cookie.

O Secure protege os cookies de serem roubados em redes não seguras, porque permite apenas o envio de cookies por conexões HTTPS. Se você não migrou totalmente seu site para HTTPS, torne isso uma prioridade.

O atributo Domain especifica quais hosts podem receber um cookie. Sua omissão vai restringir o cookie ao host do documento atual, excluindo subdomínios: o cookie de example.com será enviado em todas as solicitações para example.com, mas não nas solicitações para images.example.com. Se você tiver aplicativos diferentes em execução em subdomínios diferentes, isso reduz o risco de um domínio comprometido permitir uma porta para os outros.

Path indica o caminho que precisa existir no URL solicitado para o navegador enviar o cabeçalho Cookie. Definir Path=/ significa que o cookie será 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. Assim, ele se comporta de maneira semelhante a outros armazenamentos do lado do cliente, como LocalStorage. Não há confusão de que example.com/a pode receber valores diferentes para example.com/b.

O atributo HttpOnly adiciona alguma proteção contra scripts maliciosos de terceiros nos seus sites restringindo o acesso ao JavaScript. Ele permite que um cookie seja enviado somente em cabeçalhos de solicitação e os torna indisponíveis para 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 disponíveis para sempre. Eles são bons para cookies de curto prazo, como sessões do usuário, ou até para cookies mais curtos, como tokens para envio de formulários. Max-Age é definido em segundos e, no exemplo anterior, está definido como 7776.000 segundos, ou seja, 90 dias. Esse é um padrão razoável, que pode ser alterado dependendo do seu caso de uso.

O SameSite=Lax restringe o envio do cookie apenas em solicitações do mesmo site. Ou seja, onde a solicitação corresponde ao contexto de navegação atual, ou seja, o site de nível superior que o usuário está visitando no momento e exibido na barra de localização. SameSite=Lax é o padrão em navegadores mais recentes, mas é uma prática recomendada especificá-lo para compatibilidade com navegadores que podem ter padrões diferentes. Ao marcar explicitamente o cookie como apenas do mesmo site, você o restringe aos seus contextos primários e não precisa fazer alterações nesse cookie quando os cookies de terceiros desaparecem.

Para saber mais sobre os diferentes atributos de cookies, consulte a documentação de Set-Cookie sobre o MDN.

Se você tem um site com subdomínios e quer ter uma sessão em todos eles, o prefixo Host pode ser muito restritivo. Por exemplo, news.site pode ter subdomínios para tópicos, como finance.news.site e sport.news.site, mas é recomendável ter 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;
Detalhes

Secure é um prefixo opcional que declara menos requisitos do que Host: exige apenas que o cookie seja definido com o atributo Secure.

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 está navegando até o site de origem (por exemplo, ao seguir um link de outro site).

Você pode 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 funcionalidades que sempre estarão atrás de uma navegação inicial, como alteração de uma senha ou realização de uma compra.

A receita

Set-Cookie:
__Host-cookie-name=cookie-value;
Secure;
Path=/;
HttpOnly;
Max-Age=7776000;
SameSite=Strict;