Trabalhar com cookies SameSite no ASP.NET
SameSite é um padrão de rascunho IETF projetado para fornecer alguma proteção contra ataques CSRF (solicitação de solicitação entre sites). Originalmente redigido em 2016, o rascunho padrão foi atualizado em 2019. O padrão atualizado não é compatível com versões anteriores com o padrão anterior, sendo as seguintes diferenças mais perceptíveis:
- Cookies sem cabeçalho SameSite são tratados como
SameSite=Lax
por padrão. SameSite=None
deve ser usado para permitir o uso de cookie entre sites.- Os cookies que declaram
SameSite=None
também devem ser marcados comoSecure
. - Os aplicativos que usam
<iframe>
podem enfrentar problemas comsameSite=Lax
cookies ousameSite=Strict
porque<iframe>
são tratados como cenários entre sites. - O valor
SameSite=None
não é permitido pelo padrão de 2016 e faz com que algumas implementações tratem cookies comoSameSite=Strict
. Consulte Suporte a navegadores mais antigos neste documento.
A SameSite=Lax
configuração funciona para a maioria dos cookies de aplicativo. Algumas formas de autenticação, como OpenID Connect (OIDC) e WS-Federation, são padrão para redirecionamentos baseados em POST. Os redirecionamentos baseados em POST disparam as proteções do navegador SameSite, portanto, SameSite está desabilitado para esses componentes. A maioria dos logons do OAuth não é afetada devido a diferenças na forma como a solicitação flui.
Cada componente ASP.NET que emite cookies precisa decidir se o SameSite é apropriado.
Consulte Problemas conhecidos para problemas com aplicativos depois de instalar as atualizações do .Net SameSite 2019.
O .Net 4.7.2 e 4.8 dá suporte ao padrão de rascunho de 2019 para o SameSite desde o lançamento das atualizações em dezembro de 2019. Os desenvolvedores podem controlar programaticamente o valor do cabeçalho SameSite usando a propriedade HttpCookie.SameSite. Definir a SameSite
propriedade Strict
como , Lax
ou None
resulta na gravação desses valores na rede com o cookie. Defini-lo como igual a (SameSiteMode)(-1)
indica que nenhum cabeçalho SameSite deve ser incluído na rede com o cookie. A Propriedade HttpCookie.Secure ou 'requireSSL' em arquivos de configuração pode ser usada para marcar o cookie como Secure
ou não.
Novas HttpCookie
instâncias usarão como padrão SameSite=(SameSiteMode)(-1)
e Secure=false
. Esses padrões podem ser substituídos na seção de configuração, em system.web/httpCookies
que a cadeia de "Unspecified"
caracteres é uma sintaxe amigável somente de configuração para (SameSiteMode)(-1)
:
<configuration>
<system.web>
<httpCookies sameSite="[Strict|Lax|None|Unspecified]" requireSSL="[true|false]" />
<system.web>
<configuration>
ASP.Net também emite quatro cookies específicos para esses recursos: Autenticação Anônima, Autenticação de Formulários, Estado de Sessão e Gerenciamento de Funções. Instâncias desses cookies obtidas em runtime podem ser manipuladas usando as SameSite
propriedades e Secure
, assim como qualquer outra instância HttpCookie. No entanto, devido ao surgimento do padrão SameSite, as opções de configuração para esses quatro recursos são inconsistentes. As seções e atributos de configuração relevantes, com padrões, são mostrados abaixo. Se não houver nenhum SameSite
atributo ou Secure
relacionado para um recurso, o recurso retornará os padrões configurados na system.web/httpCookies
seção discutida acima.
<configuration>
<system.web>
<anonymousIdentification cookieRequireSSL="false" /> <!-- No config attribute for SameSite -->
<authentication>
<forms cookieSameSite="Lax" requireSSL="false" />
</authentication>
<sessionState cookieSameSite="Lax" /> <!-- No config attribute for Secure -->
<roleManager cookieRequireSSL="false" /> <!-- No config attribute for SameSite -->
<system.web>
<configuration>
Observação: 'Não especificado' só está disponível para system.web/httpCookies@sameSite
no momento. Esperamos adicionar uma sintaxe semelhante aos atributos cookieSameSite mostrados anteriormente em atualizações futuras. A configuração (SameSiteMode)(-1)
no código ainda funciona em instâncias desses cookies.*
Se você estiver lendo isso em um idioma diferente do inglês, informe-nos neste problema de discussão do GitHub se quiser ver os comentários de código em seu idioma nativo.
Para direcionar o .NET 4.7.2 ou posterior:
Verifique se web.config contém o seguinte:
<system.web> <compilation targetFramework="4.7.2"/> <httpRuntime targetFramework="4.7.2"/> </system.web>
Verifique se o arquivo de projeto contém o TargetFrameworkVersion correto:
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
O Guia de Migração do .NET tem mais detalhes.
Verifique se os pacotes NuGet no projeto são direcionados para a versão correta da estrutura. Você pode verificar a versão correta da estrutura examinando o arquivo packages.config , por exemplo:
<?xml version="1.0" encoding="utf-8"?> <packages> <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" /> <package id="Microsoft.ApplicationInsights" version="2.4.0" targetFramework="net451" /> </packages>
No arquivo packages.config anterior, o
Microsoft.ApplicationInsights
pacote:- É direcionado ao .NET 4.5.1.
- Deve ter seu
targetFramework
atributo atualizado para se houver um pacote atualizado direcionado aonet472
seu destino de estrutura.
A Microsoft não dá suporte a versões do .NET inferiores à 4.7.2 para gravar o atributo de cookie do mesmo site. Não encontramos uma maneira confiável de:
- Verifique se o atributo foi gravado corretamente com base na versão do navegador.
- Interceptar e ajustar cookies de autenticação e de sessão em versões mais antigas da estrutura.
A alteração de comportamento específica para .NET Framework é como a SameSite
propriedade interpreta o None
valor:
- Antes do patch, um valor de
None
significa:- Não emita o atributo.
- Após o patch:
- Um valor de
None
significa "Emitir o atributo com um valor deNone
". - Um
SameSite
valor de(SameSiteMode)(-1)
faz com que o atributo não seja emitido.
- Um valor de
O valor sameSite padrão para autenticação de formulários e cookies de estado de sessão foi alterado de None
para Lax
.
Se você instalar o patch e emitir um cookie com SameSite.None
, uma das duas coisas acontecerá:
- O Chrome v80 tratará esse cookie de acordo com a nova implementação e não imporá as mesmas restrições de site ao cookie.
- Qualquer navegador que não tenha sido atualizado para dar suporte à nova implementação seguirá a implementação antiga. A implementação antiga diz:
- Se você vir um valor que não entende, ignore-o e alterne para restrições estritas do mesmo site.
Portanto, o aplicativo é interrompido no Chrome ou você divide em vários outros lugares.
O suporte ao SameSite foi implementado pela primeira vez no .NET 4.7.2 usando o padrão de rascunho de 2016.
As atualizações de 19 de novembro de 2019 para o Windows atualizaram o .NET 4.7.2+ do padrão 2016 para o padrão 2019. Atualizações adicionais estão próximas para outras versões do Windows. Para obter mais informações, consulte artigos de KB que dão suporte ao SameSite no .NET Framework.
O rascunho de 2019 da especificação SameSite:
- Não é compatível com versões anteriores com o rascunho de 2016. Para obter mais informações, consulte Suporte a navegadores mais antigos neste documento.
- Especifica que os cookies são tratados como
SameSite=Lax
por padrão. - Especifica cookies que declaram
SameSite=None
explicitamente para habilitar a entrega entre sites também devem ser marcados comoSecure
. - Há suporte para patches emitidos conforme descrito na KB listada acima.
- Está programado para ser habilitado pelo Chrome por padrão em fevereiro de 2020. Os navegadores começaram a mudar para esse padrão em 2019.
Como as especificações de rascunho de 2016 e 2019 não são compatíveis, a atualização do .Net Framework de novembro de 2019 apresenta algumas alterações que podem estar falhando.
- Os cookies de Autenticação de Formulários e Estado de Sessão agora são gravados na rede como
Lax
em vez de não especificados.- Embora a maioria dos aplicativos trabalhe com
SameSite=Lax
cookies, os aplicativos que POSTam entre sites ou aplicativos que fazem uso do podem descobrir que seus cookies de autorização de formulários ou estado deiframe
sessão não estão sendo usados conforme o esperado. Para corrigir isso, altere ocookieSameSite
valor na seção de configuração apropriada, conforme discutido anteriormente.
- Embora a maioria dos aplicativos trabalhe com
- HttpCookies que definem
SameSite=None
explicitamente no código ou na configuração agora têm esse valor gravado com o cookie, enquanto ele foi omitido anteriormente. Isso pode causar problemas com navegadores mais antigos que dão suporte apenas ao padrão de rascunho de 2016.- Ao direcionar navegadores que dão suporte ao padrão de rascunho de 2019 com
SameSite=None
cookies, lembre-se de também marcá-losSecure
ou eles podem não ser reconhecidos. - Para reverter ao comportamento de 2016 de não gravar
SameSite=None
, use a configuraçãoaspnet:SupressSameSiteNone=true
do aplicativo . Observe que isso se aplicará a todos os HttpCookies no aplicativo.
- Ao direcionar navegadores que dão suporte ao padrão de rascunho de 2019 com
Consulte Serviço de Aplicativo do Azure – Manipulação de cookies SameSite e patch .NET Framework 4.7.2 para obter informações sobre como Serviço de Aplicativo do Azure está configurando comportamentos sameSite em aplicativos .Net 4.7.2.
O padrão do SameSite de 2016 determina que valores desconhecidos sejam tratados como valores SameSite=Strict
. Os aplicativos acessados de navegadores mais antigos que dão suporte ao padrão SameSite de 2016 podem ser interrompidos quando recebem uma propriedade SameSite com um valor de None
. Os aplicativos da Web devem implementar a detecção de navegador se pretenderem oferecer suporte a navegadores mais antigos. ASP.NET não implementa a detecção do navegador porque os valores de User-Agents são altamente voláteis e mudam com frequência.
A abordagem da Microsoft para corrigir o problema é ajudá-lo a implementar componentes de detecção de navegador para remover o sameSite=None
atributo de cookies se um navegador for conhecido por não dar suporte a ele. O conselho do Google era emitir cookies duplos, um com o novo atributo e outro sem o atributo. No entanto, consideramos os conselhos do Google limitados. Alguns navegadores, especialmente navegadores móveis, têm limites muito pequenos no número de cookies que um site ou um nome de domínio pode enviar. O envio de vários cookies, especialmente cookies grandes, como cookies de autenticação, pode atingir o limite do navegador móvel muito rapidamente, causando falhas de aplicativo difíceis de diagnosticar e corrigir. Além disso, como uma estrutura, há um grande ecossistema de código e componentes de terceiros que podem não ser atualizados para usar uma abordagem de cookie duplo.
O código de detecção do navegador usado nos projetos de exemplo neste repositório GitHub está contido em dois arquivos
Essas detecções são os agentes de navegador mais comuns que vimos que dão suporte ao padrão 2016 e para os quais o atributo precisa ser completamente removido. Isso não se destina a uma implementação completa:
- Seu aplicativo pode ver navegadores que nossos sites de teste não fazem.
- Você deve estar preparado para adicionar detecções conforme necessário para seu ambiente.
A forma como você conecta a detecção varia de acordo com a versão do .NET e a estrutura da Web que você está usando. O código a seguir pode ser chamado no site de chamada HttpCookie :
private void CheckSameSite(HttpContext httpContext, HttpCookie cookie)
{
if (cookie.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.UserAgent;
if (BrowserDetection.DisallowsSameSiteNone(userAgent))
{
cookie.SameSite = (SameSiteMode)(-1);
}
}
}
Consulte os seguintes tópicos de cookie do SameSite do ASP.NET 4.7.2:
Para ASP.NET 4.x, WebForms e MVC, o recurso de Reescrita de URL do IIS pode ser usado para redirecionar todas as solicitações para HTTPS. O XML a seguir mostra uma regra de exemplo:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect to https" stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{HTTPS}" pattern="Off"/>
<add input="{REQUEST_METHOD}" pattern="^get$|^head$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Em instalações locais da Reescrita de URL do IIS , há um recurso opcional que pode precisar ser instalado.
Você deve testar seu aplicativo com os navegadores compatíveis e percorrer seus cenários que envolvem cookies. Cenários de cookie normalmente envolvem
- Formulários de logon
- Mecanismos de logon externos, como Facebook, Azure AD, OAuth e OIDC
- Páginas que aceitam solicitações de outros sites
- Páginas em seu aplicativo projetadas para serem inseridas em iframes
Você deve marcar que os cookies sejam criados, persistidos e excluídos corretamente em seu aplicativo.
Os aplicativos que interagem com sites remotos, como por meio de logon de terceiros, precisam:
- Teste a interação em vários navegadores.
- Aplique a detecção e a mitigação do navegador discutidas neste documento.
Teste aplicativos Web usando uma versão do cliente que pode aceitar o novo comportamento SameSite. O Chrome, o Firefox e o Chromium Edge têm novos sinalizadores de recursos de aceitação que podem ser usados para teste. Depois que o aplicativo aplicar os patches SameSite, teste-o com versões mais antigas do cliente, especialmente o Safari. Para obter mais informações, consulte Suporte a navegadores mais antigos neste documento.
O Chrome 78+ fornece resultados enganosos porque tem uma mitigação temporária em vigor. A mitigação temporária do Chrome 78+ permite cookies com menos de dois minutos de idade. O Chrome 76 ou 77 com os sinalizadores de teste apropriados habilitados fornece resultados mais precisos. Para testar o novo comportamento do SameSite, alterne chrome://flags/#same-site-by-default-cookies
para Habilitado. Versões mais antigas do Chrome (75 e inferiores) são relatadas para falhar com a nova configuração None
. Consulte Suporte a navegadores mais antigos neste documento.
O Google não disponibiliza versões mais antigas do Chrome. Siga as instruções em Baixar Chromium para testar versões mais antigas do Chrome. Não baixe o Chrome de links fornecidos pesquisando versões mais antigas do Chrome.
- Chromium 76 Win64
- Chromium 74 Win64
- Se você não estiver usando uma versão de 64 bits do Windows, poderá usar o visualizador Chromium Dash para pesquisar qual branch Chromium corresponde ao Chrome 74 (v74.0.3729.108) usando as instruções fornecidas pelo Chromium.
A partir da versão 80.0.3975.0
canário, a mitigação temporária lax+POST pode ser desabilitada para fins de teste usando o novo sinalizador --enable-features=SameSiteDefaultChecksMethodRigorously
para permitir testes de sites e serviços no estado final eventual do recurso em que a mitigação foi removida. Para obter mais informações, consulte Atualizações do SameSite do The Chromium Projects
Baixe uma versão do Chrome que dê suporte ao novo atributo. No momento da gravação, a versão atual é o Chrome 80. O Chrome 80 precisa do sinalizador chrome://flags/#same-site-by-default-cookies
habilitado para usar o novo comportamento. Você também deve habilitar (chrome://flags/#cookies-without-same-site-must-be-secure
) para testar o comportamento futuro de cookies que não têm o mesmo Atributo de site habilitado. O Chrome 80 está no destino para fazer a opção de tratar cookies sem o atributo como SameSite=Lax
, embora com um período de carência cronometrado para determinadas solicitações. Para desabilitar o período de carência cronometrado, o Chrome 80 pode ser iniciado com o seguinte argumento de linha de comando:
--enable-features=SameSiteDefaultChecksMethodRigorously
O Chrome 80 tem mensagens de aviso no console do navegador sobre atributos sameSite ausentes. Use F12 para abrir o console do navegador.
O Safari 12 implementou estritamente o rascunho anterior e falha quando o novo None
valor está em um cookie. None
é evitado por meio do código de detecção do navegador Suporte a navegadores mais antigos neste documento. Teste os logons de estilo do sistema operacional baseados em Safari 12, Safari 13 e WebKit usando MSAL, ADAL ou qualquer biblioteca que você esteja usando. O problema depende da versão subjacente do sistema operacional. Sabe-se que o OSX Mojave (10.14) e o iOS 12 têm problemas de compatibilidade com o novo comportamento do SameSite. A atualização do SO para o OSX Catalina (10.15) ou iOS 13 corrige o problema. No momento, o Safari não tem um sinalizador de aceitação para testar o novo comportamento de especificação.
O suporte do Firefox ao novo padrão pode ser testado na versão 68+ aceitando-o na página about:config
com o sinalizador de recurso network.cookie.sameSite.laxByDefault
. Não houve relatos de problemas de compatibilidade com versões mais antigas do Firefox.
O Edge dá suporte ao antigo padrão SameSite. A versão 44+ do Edge não tem problemas de compatibilidade conhecidos com o novo padrão.
Os sinalizadores SameSite são definidos na página edge://flags/#same-site-by-default-cookies
. Nenhum problema de compatibilidade foi descoberto com o Edge Chromium.
As versões do Electron incluem versões mais antigas do Chromium. Por exemplo, a versão do Electron usada pelo Teams é Chromium 66, que exibe o comportamento mais antigo. Você deve executar seu próprio teste de compatibilidade com a versão do Electron que seu produto usa. Consulte Suporte a navegadores mais antigos.
Você pode reverter o comportamento atualizado do sameSite em aplicativos .NET Framework ao comportamento anterior em que o atributo sameSite não é emitido para um valor de None
e reverter os cookies de autenticação e de sessão para não emitir o valor. Isso deve ser visto como uma correção extremamente temporária, pois as alterações do Chrome interromperão quaisquer solicitações POST externas ou autenticação para usuários que usam navegadores que dão suporte às alterações no padrão.
Atualize web.config para incluir as seguintes definições de configuração:
<configuration>
<appSettings>
<add key="aspnet:SuppressSameSiteNone" value="true" />
</appSettings>
<system.web>
<authentication>
<forms cookieSameSite="None" />
</authentication>
<sessionState cookieSameSite="None" />
</system.web>
</configuration>
- Alterações futuras de cookie SameSite em ASP.NET e ASP.NET Core
- Dicas para testar e depurar SameSite por padrão e "SameSite=None; Cookies seguros
- Chromium Blog:Developers: Get Ready for New SameSite=None; Proteger configurações de cookie
- Cookies sameSite explicados
- Chrome Atualizações
- Patches sameSite do .NET
- Informações do mesmo site de aplicativos Web do Azure
- Informações do mesmo site do Azure ActiveDirectory