Trabalhe com cookies SameSite no ASP.NET Core
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 o 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.- Cookies que declaram
SameSite=None
também devem ser marcados comoSecure
. - Os aplicativos que usam
<iframe>
podem enfrentar problemas com cookiessameSite=Lax
ousameSite=Strict
porque<iframe>
é tratado 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 configuração SameSite=Lax
funciona para a maioria dos cookies dos aplicativos. 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 Core que emite cookies precisa decidir se o SameSite é apropriado.
SameSite e Identity
A Identity do ASP.NET Core não é substancialmente afetada pelos cookies SameSite, exceto por cenários avançados, como integração de IFrames
ou OpenIdConnect
.
Ao usar Identity
, não adicione nenhum provedor cookie ou chame services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
, o Identity
cuida disso.
Código de exemplo de teste SameSite
O seguinte exemplo pode ser baixado e testado:
Amostra | Documento |
---|---|
Razor Pages do ASP.NET Core | Amostra de Razor Pages SameSite cookie do ASP.NET Core 3.1 |
Suporte do .NET Core para o atributo SameSite
O .NET Core dá suporte ao padrão de rascunho de 2019 para SameSite. Os desenvolvedores podem controlar programaticamente o valor do atributo SameSite usando a propriedade HttpCookie.SameSite
. Definir a propriedade SameSite
como Strict
, Lax
ou None
resulta na gravação desses valores na rede com o cookie. Definir como SameSiteMode.Unspecified
indica que nenhum SameSite deve ser enviado com o cookie.
var cookieOptions = new CookieOptions
{
// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS.
Secure = true,
// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
HttpOnly = true,
// Add the SameSite attribute, this will emit the attribute with a value of none.
SameSite = SameSiteMode.None
// The client should follow its default cookie policy.
// SameSite = SameSiteMode.Unspecified
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
}
Uso de API com SameSite
HttpContext.Response.Cookies.Append usa Unspecified
como padrão, o que significa que nenhum atributo SameSite adicionado ao cookie e ao cliente usará seu comportamento padrão (Lax para novos navegadores, None para os antigos). O código a seguir mostra como alterar o valor cookie do SameSite para SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Todos os componentes ASP.NET Core que emitem cookies substituem os padrões anteriores por configurações apropriadas para seus cenários. Os valores padrão anteriores substituídos não foram alterados.
ASP.NET Core 3.1 e posterior fornece o seguinte suporte ao SameSite:
- Redefine o comportamento de
SameSiteMode.None
para emitirSameSite=None
- Adiciona um novo valor
SameSiteMode.Unspecified
para omitir o atributo SameSite. - Todas as APIs de cookies tem o padrão
Unspecified
. Alguns componentes que usam cookies definem valores mais específicos para seus cenários. Consulte a tabela acima para exemplos.
No ASP.NET Core 3.0 e posterior, os padrões do SameSite foram alterados para evitar conflitos com padrões de cliente inconsistentes. As seguintes APIs alteraram o padrão de SameSiteMode.Lax
para -1
para evitar a emissão de um atributo SameSite para estes cookies:
- CookieOptions usado com HttpContext.Response.Cookies.Append
- CookieBuilder usado como uma fábrica para
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Histórico e alterações
O suporte ao SameSite foi implementado pela primeira vez em ASP.NET Core em 2.0 usando o padrão de rascunho de 2016. O padrão de 2016 era opcional. ASP.NET Core aceitou ao definir vários cookies como Lax
por padrão. Depois de encontrar vários problemas com a autenticação, a maioria do uso do SameSite foi desabilitada.
Os patches foram emitidos em novembro de 2019 para atualizar do padrão 2016 para o padrão 2019. 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 cookies são tratados como
SameSite=Lax
por padrão. - Especifica cookies que declaram
SameSite=None
explicitamente para habilitar a entrega entre sites deve ser marcado comoSecure
.None
é uma nova entrada a ser recusada. - Há suporte para patches emitidos para ASP.NET Core 2.1, 2.2 e 3.0. ASP.NET Core 3.1 e posterior tem suporte adicional ao SameSite.
- 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.
APIs afetadas pela alteração do padrão de rascunho SameSite de 2016 para o padrão de rascunho de 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Suporte a navegadores mais antigos
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 Core não implementa a detecção de navegador porque os valores de User-Agents são altamente voláteis e mudam com frequência. Um ponto de extensão no Microsoft.AspNetCore.CookiePolicy permite conectar User-Agent lógica específica.
No Program.cs
, adicione o código que chama UseCookiePolicy antes de chamar UseAuthentication ou qualquer método que grave cookies:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
No Program.cs
, adicione um código semelhante ao seguinte código realçado:
var builder = WebApplication.CreateBuilder(args);
builder.Services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
builder.Services.AddRazorPages();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
No exemplo anterior, MyUserAgentDetectionLib.DisallowsSameSiteNone
é uma biblioteca fornecida pelo usuário que detecta se o agente do usuário não dá suporte ao None
do SameSite:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
O código a seguir mostra um método DisallowsSameSiteNone
de exemplo:
Aviso
O código a seguir é apenas para demonstração:
- Não deve ser considerado completo.
- Ele não é mantido ou suportado.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(userAgent))
return false;
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking
// stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
Testar aplicativos para problemas do SameSite
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 Política de cookies de navegador de detecção e a mitigação 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.
Testar com o Chrome
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. 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.
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
Testar com o Safari
O Safari 12 implementou estritamente o rascunho anterior e falhará quando o novo valor None
estiver 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.
Testar com o Firefox
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.
Testar com o navegador Edge
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.
Testar com o Edge (Chromium)
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.
Testar com Electron
As versões do Electron incluem versões mais antigas do Chromium. Por exemplo, a versão do Electron usada pelo Microsoft Teams é a Chromium 66, que exibe o comportamento mais antigo. Você precisa executar seu próprio teste de compatibilidade com a versão do Electron que o seu produto usa. Consulte Suporte a navegadores mais antigos na seção a seguir.
Recursos adicionais
- Blog do Chromium:Devenvolvedores: Prepare-se para o novo SameSite=None; Configurações Cookie Seguras
- Cookies SameSite explicados
- Patches de novembro de 2019
Amostra | Documento |
---|---|
Razor Pages do ASP.NET Core | Amostra de Razor Pages SameSite cookie do ASP.NET Core 3.1 |
O seguinte exemplo pode ser baixado e testado:
Amostra | Documento |
---|---|
Razor Pages do ASP.NET Core | Amostra de Razor Pages SameSite cookie do ASP.NET Core 3.1 |
Suporte do .NET Core para o atributo SameSite
O .NET Core 3.1 e posterior dá suporte ao padrão de rascunho de 2019 para o SameSite. Os desenvolvedores podem controlar programaticamente o valor do atributo SameSite usando a propriedade HttpCookie.SameSite
. Definir a propriedade SameSite
como Strict, Lax ou None resulta na gravação desses valores na rede com o cookie. Defini-lo como igual a (SameSiteMode)(-1)
indica que nenhum atributo SameSite deve ser incluído na rede com o cookie
var cookieOptions = new CookieOptions
{
// Set the secure flag, which Chrome's changes will require for SameSite none.
// Note this will also require you to be running on HTTPS.
Secure = true,
// Set the cookie to HTTP only which is good practice unless you really do need
// to access it client side in scripts.
HttpOnly = true,
// Add the SameSite attribute, this will emit the attribute with a value of none.
// To not emit the attribute at all set
// SameSite = (SameSiteMode)(-1)
SameSite = SameSiteMode.None
};
// Add the cookie to the response cookie collection
Response.Cookies.Append("MyCookie", "cookieValue", cookieOptions);
O .NET Core 3.1 e posterior dá suporte aos valores SameSite atualizados e adiciona um valor de enumeração extra, SameSiteMode.Unspecified
à enumeração SameSiteMode
.
Esse novo valor indica que nenhum SameSite deve ser enviado com o cookie.
Uso de API com SameSite
HttpContext.Response.Cookies.Append usa Unspecified
como padrão, o que significa que nenhum atributo SameSite adicionado ao cookie e ao cliente usará seu comportamento padrão (Lax para novos navegadores, None para os antigos). O código a seguir mostra como alterar o valor cookie do SameSite para SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Todos os componentes ASP.NET Core que emitem cookies substituem os padrões anteriores por configurações apropriadas para seus cenários. Os valores padrão anteriores substituídos não foram alterados.
ASP.NET Core 3.1 e posterior fornece o seguinte suporte ao SameSite:
- Redefine o comportamento de
SameSiteMode.None
para emitirSameSite=None
- Adiciona um novo valor
SameSiteMode.Unspecified
para omitir o atributo SameSite. - Todas as APIs de cookies tem o padrão
Unspecified
. Alguns componentes que usam cookies definem valores mais específicos para seus cenários. Consulte a tabela acima para exemplos.
No ASP.NET Core 3.0 e posterior, os padrões do SameSite foram alterados para evitar conflitos com padrões de cliente inconsistentes. As seguintes APIs alteraram o padrão de SameSiteMode.Lax
para -1
para evitar a emissão de um atributo SameSite para estes cookies:
- CookieOptions usado com HttpContext.Response.Cookies.Append
- CookieBuilder usado como uma fábrica para
CookieOptions
- CookiePolicyOptions.MinimumSameSitePolicy
Histórico e alterações
O suporte ao SameSite foi implementado pela primeira vez em ASP.NET Core em 2.0 usando o padrão de rascunho de 2016. O padrão de 2016 era opcional. ASP.NET Core aceitou ao definir vários cookies como Lax
por padrão. Depois de encontrar vários problemas com a autenticação, a maioria do uso do SameSite foi desabilitada.
Os patches foram emitidos em novembro de 2019 para atualizar do padrão 2016 para o padrão 2019. 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 cookies são tratados como
SameSite=Lax
por padrão. - Especifica cookies que declaram
SameSite=None
explicitamente para habilitar a entrega entre sites deve ser marcado comoSecure
.None
é uma nova entrada a ser recusada. - Há suporte para patches emitidos para ASP.NET Core 2.1, 2.2 e 3.0. ASP.NET Core 3.1 tem suporte adicional ao SameSite.
- 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.
APIs afetadas pela alteração do padrão de rascunho SameSite de 2016 para o padrão de rascunho de 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Suporte a navegadores mais antigos
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 Core não implementa a detecção de navegador porque os valores de User-Agents são altamente voláteis e mudam com frequência. Um ponto de extensão no Microsoft.AspNetCore.CookiePolicy permite conectar User-Agent lógica específica.
No Startup.Configure
, adicione o código que chama UseCookiePolicy antes de chamar UseAuthentication ou qualquer método que grave cookies:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Em Startup.ConfigureServices
, adicione um código semelhante ao seguinte:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
services.AddRazorPages();
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
}
}
No exemplo anterior, MyUserAgentDetectionLib.DisallowsSameSiteNone
é uma biblioteca fornecida pelo usuário que detecta se o agente do usuário não dá suporte ao None
do SameSite:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
O código a seguir mostra um método DisallowsSameSiteNone
de exemplo:
Aviso
O código a seguir é apenas para demonstração:
- Não deve ser considerado completo.
- Ele não é mantido ou suportado.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(userAgent))
return false;
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking
// stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
Testar aplicativos para problemas do SameSite
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 Política de cookies de navegador de detecção e a mitigação 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.
Testar com o Chrome
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. 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.
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
Testar com o Safari
O Safari 12 implementou estritamente o rascunho anterior e falhará quando o novo valor None
estiver 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.
Testar com o Firefox
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.
Testar com o navegador Edge
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.
Testar com o Edge (Chromium)
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.
Testar com Electron
As versões do Electron incluem versões mais antigas do Chromium. Por exemplo, a versão do Electron usada pelo Microsoft Teams é a Chromium 66, que exibe o comportamento mais antigo. Você precisa executar seu próprio teste de compatibilidade com a versão do Electron que o seu produto usa. Consulte Suporte a navegadores mais antigos na seção a seguir.
Recursos adicionais
- Blog do Chromium:Devenvolvedores: Prepare-se para o novo SameSite=None; Configurações Cookie Seguras
- Cookies SameSite explicados
- Patches de novembro de 2019
Amostra | Documento |
---|---|
Razor Pages do ASP.NET Core | Amostra de Razor Pages SameSite cookie do ASP.NET Core 3.1 |
Os seguintes exemplos podem ser baixados e testados:
Amostra | Documento |
---|---|
MVC do .NET Core | Amostra de MVC do SameSite cookie do ASP.NET Core 2.1 |
Razor Pages do ASP.NET Core | Amostra de Razor Pages SameSite cookie do ASP.NET Core 2.1 |
Alterações de comportamento de patch de dezembro
A alteração de comportamento específica para .NET Framework e .NET Core 2.1 é como a propriedade SameSite
interpreta o valor None
. Antes do patch, um valor de None
significava "Não emitir o atributo de forma alguma", após o patch, significa "Emitir o atributo com um valor de None
". Após o patch, um valor SameSite
de (SameSiteMode)(-1)
faz com que o atributo não seja emitido.
O valor SameSite padrão para cookies de autenticação de formulários e estado de sessão foi alterado de None
para Lax
.
Uso de API com SameSite
HttpContext.Response.Cookies.Append usa Unspecified
como padrão, o que significa que nenhum atributo SameSite adicionado ao cookie e ao cliente usará seu comportamento padrão (Lax para novos navegadores, None para os antigos). O código a seguir mostra como alterar o valor cookie do SameSite para SameSiteMode.Lax
:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Todos os componentes ASP.NET Core que emitem cookies substituem os padrões anteriores por configurações apropriadas para seus cenários. Os valores padrão anteriores substituídos não foram alterados.
Histórico e alterações
O suporte ao SameSite foi implementado pela primeira vez em ASP.NET Core em 2.0 usando o padrão de rascunho de 2016. O padrão de 2016 era opcional. ASP.NET Core aceitou ao definir vários cookies como Lax
por padrão. Depois de encontrar vários problemas com a autenticação, a maioria do uso do SameSite foi desabilitada.
Os patches foram emitidos em novembro de 2019 para atualizar do padrão 2016 para o padrão 2019. 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 cookies são tratados como
SameSite=Lax
por padrão. - Especifica cookies que declaram
SameSite=None
explicitamente para habilitar a entrega entre sites deve ser marcado comoSecure
.None
é uma nova entrada a ser recusada. - Há suporte para patches emitidos para ASP.NET Core 2.1, 2.2 e 3.0. ASP.NET Core 3.1 tem suporte adicional ao SameSite.
- 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.
APIs afetadas pela alteração do padrão de rascunho SameSite de 2016 para o padrão de rascunho de 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Suporte a navegadores mais antigos
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 Core não implementa a detecção de navegador porque os valores de User-Agents são altamente voláteis e mudam com frequência. Um ponto de extensão no Microsoft.AspNetCore.CookiePolicy permite conectar User-Agent lógica específica.
No Startup.Configure
, adicione o código que chama UseCookiePolicy antes de chamar UseAuthentication ou qualquer método que grave cookies:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
Em Startup.ConfigureServices
, adicione um código semelhante ao seguinte:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.MinimumSameSitePolicy = (SameSiteMode)(-1);
options.OnAppendCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
options.OnDeleteCookie = cookieContext =>
CheckSameSite(cookieContext.Context, cookieContext.CookieOptions);
});
services.AddRazorPages();
}
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = (SameSiteMode)(-1);
}
}
}
No exemplo anterior, MyUserAgentDetectionLib.DisallowsSameSiteNone
é uma biblioteca fornecida pelo usuário que detecta se o agente do usuário não dá suporte ao None
do SameSite:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
O código a seguir mostra um método DisallowsSameSiteNone
de exemplo:
Aviso
O código a seguir é apenas para demonstração:
- Não deve ser considerado completo.
- Ele não é mantido ou suportado.
public static bool DisallowsSameSiteNone(string userAgent)
{
// Check if a null or empty string has been passed in, since this
// will cause further interrogation of the useragent to fail.
if (String.IsNullOrWhiteSpace(userAgent))
return false;
// Cover all iOS based browsers here. This includes:
// - Safari on iOS 12 for iPhone, iPod Touch, iPad
// - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
// - Chrome on iOS 12 for iPhone, iPod Touch, iPad
// All of which are broken by SameSite=None, because they use the iOS networking
// stack.
if (userAgent.Contains("CPU iPhone OS 12") ||
userAgent.Contains("iPad; CPU OS 12"))
{
return true;
}
// Cover Mac OS X based browsers that use the Mac OS networking stack.
// This includes:
// - Safari on Mac OS X.
// This does not include:
// - Chrome on Mac OS X
// Because they do not use the Mac OS networking stack.
if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
userAgent.Contains("Version/") && userAgent.Contains("Safari"))
{
return true;
}
// Cover Chrome 50-69, because some versions are broken by SameSite=None,
// and none in this range require it.
// Note: this covers some pre-Chromium Edge versions,
// but pre-Chromium Edge does not require SameSite=None.
if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
{
return true;
}
return false;
}
Testar aplicativos para problemas do SameSite
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 Política de cookies de navegador de detecção e a mitigação 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.
Testar com o Chrome
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. 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.
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
Testar com o Safari
O Safari 12 implementou estritamente o rascunho anterior e falhará quando o novo valor None
estiver 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.
Testar com o Firefox
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.
Testar com o navegador Edge
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.
Testar com o Edge (Chromium)
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.
Testar com Electron
As versões do Electron incluem versões mais antigas do Chromium. Por exemplo, a versão do Electron usada pelo Microsoft Teams é a Chromium 66, que exibe o comportamento mais antigo. Você precisa executar seu próprio teste de compatibilidade com a versão do Electron que o seu produto usa. Consulte Suporte a navegadores mais antigos na seção a seguir.
Recursos adicionais
- Blog do Chromium:Devenvolvedores: Prepare-se para o novo SameSite=None; Configurações Cookie Seguras
- Cookies SameSite explicados
- Patches de novembro de 2019
Amostra | Documento |
---|---|
MVC do .NET Core | Amostra de MVC do SameSite cookie do ASP.NET Core 2.1 |
Razor Pages do ASP.NET Core | Amostra de Razor Pages SameSite cookie do ASP.NET Core 2.1 |