Hero Image

Cookies SameSite explicados

Cookies SameSite explicados

Proteja seu site aprendendo como marcar explicitamente cookies cross-site.

Updated
Appears in: Safe and secure

Este artigo faz parte de uma série sobre alterações em atributos do cookie SameSite

Cookies são um dos métodos disponíveis para adicionar estado persistente a sites. Com o passar dos anos, suas capacidades cresceram e evoluíram, mas deixaram a plataforma com alguns problemas legados problemáticos. Para resolver isso, os navegadores (incluindo Chrome, Firefox e Edge) estão mudando seu comportamento para impor mais padrões de preservação da privacidade.

Cada cookie é um par chave=valor (key=value) junto com uma série de atributos que controlam quando e onde o cookie é usado. Você provavelmente já usou esses atributos para definir coisas como datas de expiração ou indicar que o cookie só deve ser enviado por HTTPS. Os servidores definem cookies enviando o cabeçalho Set-Cookie na sua resposta. Para saber todos os detalhes, você pode mergulhar no RFC6265bis, mas aqui você pode ter uma introdução rápida.

Digamos que você tenha um blog no qual deseja exibir uma promoção "O que há de novo" para seus usuários. Os usuários podem dispensar a promoção e assim eles não irão vê-la novamente por um tempo. Você pode armazenar essa preferência em um cookie, configurá-lo para expirar em um mês (2.600.000 segundos) e enviá-lo apenas por HTTPS. O cabeçalho ficaria assim:

Set-Cookie: promo_shown=1; Max-Age=2600000; Secure
Três cookies sendo enviados para um navegador por um servidor em uma resposta HTTP
Servers set cookies using the Set-Cookie header.

Quando o leitor visualizar uma página que atende a esses requisitos, ou seja, quando estiver numa conexão segura e o cookie tenha menos de um mês de vida, o navegador enviará este cabeçalho na sua solicitação HTTP:

Cookie: promo_shown=1
Três cookies sendo enviados de um navegador para um servidor numa solicitação HTTP
Seu navegador devolve os cookies através do cabeçalho Cookie.

Você também pode adicionar e ler os cookies disponíveis para esse site em JavaScript através de document.cookie. Atribuir um par chave=valor a document.cookie cria ou substitui um cookie com essa chave. Por exemplo, você pode experimentar o seguinte código no console JavaScript do seu navegador:

> document.cookie = "promo_shown=1; Max-Age=2600000; Secure"
< "promo_shown=1; Max-Age=2600000; Secure"

A leitura de document.cookie devolve todos os cookies acessíveis no contexto atual, com cada cookie separado por um ponto e vírgula:

> document.cookie;
< "promo_shown=1; color_theme=peachpuff; sidebar_loc=left"
JavaScript acessando cookies no navegador
JavaScript pode accessar cookies usando document.cookie.

Se você tentar isso numa seleção de sites populares, notará que a maioria deles define muito mais do que apenas três cookies. Na maioria dos casos, esses cookies são enviados a cada solicitação para esse domínio, o que tem uma série de implicações. A largura de banda de upload geralmente é mais restrita que o download para seus usuários, de modo que a sobrecarga em todas as solicitações de saída estará adicionando um atraso no seu tempo para o primeiro byte. Seja conservador no número e no tamanho dos cookies que você define. Use o atributo Max-Age para ajudar a garantir que os cookies não durem mais do que o necessário.

O que são cookies primários e de terceiros? #

Se você voltar para a mesma seleção de sites que estava olhando antes, deve ter percebido que havia cookies para uma variedade de domínios, não apenas aquele que você estava visitando no momento. Os cookies que correspondem ao domínio do site atual (o domínio exibido na barra de endereços do navegador) são chamados de cookies primários. Da mesma forma, os cookies de domínios diferentes do site atual são chamados de cookies de terceiros. Isto não é um rótulo absoluto, mas relativo ao contexto do usuário; o mesmo cookie pode ser original ou de terceiros, dependendo do site no qual o usuário se encontra no momento.

Três cookies sendo enviados para um navegador a partir de solicitações diferentes na mesma página
Os cookies podem vir de uma variedade de domínios diferentes em uma página.

Continuando o exemplo acima, vamos supor que uma de suas postagens de blog tenha uma foto de um gato particularmente incrível e está hospedada em /blog/img/amazing-cat.png. Por ser uma imagem tão incrível, outra pessoa a usa diretamente em seu site. Se um visitante esteve no seu site e possui o cookie promo_shown, quando ele visualizar o amazing-cat.png no site da outra pessoa, esse cookie será enviado como parte da solicitação de imagem. Isso é completamente inútil, já que promo_shown não é usado para nada no site dessa outra pessoa, ele apenas acrescenta uma sobrecarga à solicitação.

Se for um efeito não intencional, por que alguém o faria? É esse mecanismo que permite que os sites mantenham o estado quando estão sendo usados num contexto de terceiros. Por exemplo, se você incorporar um vídeo do YouTube no seu site, os visitantes verão uma opção "Assistir mais tarde" no player. Se o seu visitante já estiver conectado ao YouTube, essa sessão está sendo disponibilizada no player incorporado por um cookie de terceiros, o que significa que o botão "Assistir mais tarde" salvará o vídeo de uma vez ao invés de solicitar que ele faça login ou tenha que navegar para fora de sua página e de volta para o YouTube.

O mesmo cookie sendo enviado em três contextos diferentes
Um cookie em um contexto de terceiros é enviado ao visitar páginas diferentes.

Uma das propriedades culturais da web é que ela tende a ser aberta por default. Isto é parte do que tem permitido que tantas pessoas criassem seus próprios conteúdos e aplicativos nela. No entanto, isso também trouxe uma série de questões relacionadas a segurança e privacidade. Os ataques de falsificação de solicitação entre sites (CSRF - Cross-Site Request Forgery) baseiam-se no fato de que os cookies são anexados a qualquer solicitação para uma determinada origem, independentemente de quem inicia a solicitação. Por exemplo, se você visitar evil.example, ele pode acionar solicitações para your-blog.example, e seu navegador anexará imediatamente os cookies associados. Se o seu blog não tiver cuidado com a forma como valida essas solicitações, o site evil.example poderá desencadear ações como excluir postagens ou adicionar conteúdo.

Os usuários também estão se conscientizando de como cookies podem ser usados para rastrear as atividades deles através de múltiplos sites. No entanto, até agora não houve uma maneira de declarar explicitamente sua intenção com o cookie. Seu promo_shown só pode ser enviado num contexto primário, enquanto um cookie de sessão para um widget que deve ser incorporado em outros sites está intencionalmente lá para fornecer o estado de usuário logado num contexto de terceiros.

Declare explicitamente o uso de cookies com o atributo SameSite #

A introdução do SameSite (definido em RFC6265bis ) permite que você declare se seu cookie deve ser restrito a um contexto primário ou do mesmo site. É útil entender exatamente o que 'site' significa aqui. O site é a combinação do sufixo do domínio e a parte do domínio imediatamente anterior. Por exemplo, o www.web.dev faz parte do site web.dev

Key Term:

Se o usuário estiver em www.web.dev e solicitar uma imagem de static.web.dev, isto será considerado uma solicitação do mesmo site.

Quem define o que é um sufixo de domínio é a lista de sufixos públicos, portanto, a distinção não se restringe apenas a domínios de nível superior como .com mas também inclui serviços como github.io. Isto permite que your-project.github.io e my-project.github.io sejam contados como sites separados.

Key Term:

Se o usuário estiver em your-project.github.io e solicitar uma imagem de my-project.github.io, isto será considerado uma solicitação entre sites.

A introdução do atributo SameSite num cookie fornece três maneiras diferentes de controlar esse comportamento. Você pode optar por não especificar o atributo ou pode usar os valores Strict ou Lax para restringir o cookie a solicitações do mesmo site.

Se você definir SameSite como Strict, seu cookie será enviado apenas num contexto primário. Do ponto de vista do usuário, o cookie só será enviado se o site do cookie corresponder ao site atualmente mostrado na barra de URL do navegador. Portanto, se o cookie promo_shown for definido da seguinte maneira:

Set-Cookie: promo_shown=1; SameSite=Strict

Quando o usuário estiver no seu site, o cookie será enviado junto com a solicitação como esperado. No entanto, ao seguir um link para o seu site, digamos de outro site ou através do e-mail de um amigo, nessa solicitação inicial o cookie não será enviado. Isto é bom quando você tem cookies relacionados à funcionalidade que sempre deve estar associada a uma navegação inicial, como a alteração de uma senha ou a realização de uma compra, mas é muito restritiva para promo_shown. Se o seu leitor seguir o link para o site, ele deseja que o cookie seja enviado para que sua preferência possa ser aplicada.

É aí que entra SameSite=Lax, que permite que o cookie seja enviado com essas navegações de nível superior. Vamos revisitar o exemplo do artigo sobre gatos acima, onde outro site está referenciando seu conteúdo. Eles usam sua foto do gato diretamente e fornecem um link para o seu artigo original.

<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>

E o cookie foi definido como:

Set-Cookie: promo_shown=1; SameSite=Lax

Quando o leitor estiver no blog de outra pessoa, o cookie não será enviado quando o navegador solicitar o amazing-cat.png. No entanto, quando o leitor seguir o link para cat.html no seu blog, essa solicitação incluirá o cookie. Isto faz com que o valor Lax seja uma boa escolha para cookies que afetam a exibição do site. O valor Strict é útil para cookies relacionados às ações que seu usuário está realizando.

Caution:

Nem Strict nem Lax são uma solução completa para a segurança do seu site. Os cookies são enviados como parte da solicitação do usuário e você deve tratá-los da mesma forma que qualquer outra entrada do usuário. Isto significa higienizar e validar a entrada. Nunca use um cookie para armazenar dados que você considera segredo que deveria ficar do lado do servidor.

Por último, existe a opção de não especificar o valor. Anteriormente, esta era a forma de indicar implicitamente o desejo de que o cookie fosse enviado em todos os contextos. No último rascunho da RFC6265bis, isto foi explicitado pela introdução de um novo valor de SameSite=None. Isto significa que você pode usar None para comunicar claramente seu desejo intencional de que o cookie seja enviado num contexto de terceiros.

Três cookies rotulados como None, Lax ou Strict dependendo do contexto
Marque explicitamente o contexto de um cookie como None, Lax ou Strict

Se você fornece um serviço que outros sites consomem, como widgets, conteúdo incorporado, programas de afiliados, publicidade ou login em vários sites, você deve usar None para garantir que sua intenção seja clara.

Mudanças ao comportamento default sem SameSite #

Embora o SameSite seja amplamente suportado, infelizmente ele não tem sido amplamente adotado pelos desenvolvedores. O padrão default de envio de cookies para todos os lugares significa que todos os casos de uso funcionam, mas deixa o usuário vulnerável a CSRF e vazamento não intencional de informações. Para encorajar os desenvolvedores a declarar suas intenções e fornecer aos usuários uma experiência mais segura, a proposta da IETF, Incrementally Better Cookies apresenta duas mudanças principais:

  • Cookies sem um SameSite serão tratados como SameSite=Lax.
  • Cookies com SameSite=None também devem especificar Secure, o que significa que requerem um contexto seguro.

O Chrome implementa esse comportamento default a partir da versão 84. O Firefox suporta experimentalmente a partir do Firefox 69 e será comportamento default no futuro. Para testar esses comportamentos no Firefox, abra about:config e ative network.cookie.sameSite.laxByDefault. O Edge também tem planos de mudar seus comportamentos padrão.

Este artigo será atualizado à medida que navegadores adicionais anunciarem suporte.

SameSite=Lax por default #

No attribute set

Set-Cookie: promo_shown=1

Se você enviar um cookie sem nenhum atributo SameSite especificado…

Default behavior applied

Set-Cookie: promo_shown=1; SameSite=Lax

O navegador tratará esse cookie como se SameSite=Lax tivesse sido especificado.

Embora a intenção seja aplicar um padrão mais seguro, o ideal é definir um SameSite explícito, em vez de depender do navegador para aplicá-lo para você. Isto deixa sua intenção para o cookie explícita e aumenta as chances de uma experiência consistente em todos os navegadores.

Caution:

O comportamento default aplicado pelo Chrome é ligeiramente mais permissivo do que um SameSite=Lax explícito, pois permitirá que certos cookies sejam enviados em solicitações POST de nível superior. Você pode ver exatamente com isto funciona no anúncio blink-dev. Isto foi proposto como uma mitigação temporária: você deve continuar a corrigir seus cookies cross-site para usar SameSite=None; Secure.

SameSite=None precisa ser seguro #

Rejected

Set-Cookie: widget_session=abc123; SameSite=None

A configuração de um cookie sem Secure será rejeitada.

Accepted

Set-Cookie: widget_session=abc123; SameSite=None; Secure

Você deve garantir que SameSite=None seja emparelhado com o atributo Secure

Você pode testar esse comportamento a partir do Chrome 76 ativando about://flags/#cookies-without-same-site-must-be-secure e no Firefox 69 em about:config definindo network.cookie.sameSite.noneRequiresSecure.

Você vai querer aplicar esse recurso ao definir novos cookies e atualizar ativamente os cookies existentes, mesmo que eles não estejam se aproximando da data de expiração.

Se você depende de qualquer serviço que forneça conteúdo de terceiros em seu site, verifique também com o provedor se ele está atualizando seus serviços. Poderá ser necessário atualizar suas dependências ou fragmentos de código para garantir que seu site adote o novo comportamento.

Ambas as alterações são compatíveis com os navegadores que implementaram corretamente a versão anterior do atributo SameSite ou simplesmente não o suportam. Ao aplicar essas alterações aos seus cookies, você torna explícito o uso pretendido, em vez de confiar no comportamento padrão do navegador. Da mesma forma, qualquer cliente que ainda não reconheça SameSite=None deve ignorá-lo e continuar como se o atributo não tivesse sido definido.

Warning:

Várias versões mais antigas de navegadores, incluindo Chrome, Safari e navegador UC, são incompatíveis com o novo atributo None e podem ignorar ou restringir o cookie. Esse comportamento é corrigido nas versões atuais, mas você deve verificar seu tráfego para saber qual a proporção de seus usuários que foram afetados. Você poderá ver a lista de clientes incompatíveis conhecidos no site do Chromium.

Receitas de cookies SameSite #

Para mais detalhes sobre como atualizar seus cookies para lidar com essas mudanças de SameSite=None e as diferenças de comportamento em diferentes navegadores, acesse o artigo seguinte, Receitas de cookies SameSite.

Muito obrigado pelas contribuições e feedback de Lily Chen, Malte Ubl, Mike West, Rob Dodson, Tom Steiner e Vivek Sekhar

Imagem do Cookie Hero por Pille-Riin Priske no Unsplash

Last updated: Improve article