Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Por Rick Anderson
SameSite es un estándar de borrador de IETF diseñado para proporcionar cierta protección contra ataques de falsificación de solicitud entre sitios (CSRF). Redactado originalmente en 2016, el borrador del estándar se actualizó en 2019. El estándar actualizado no es retrocompatible con el estándar anterior, siendo las diferencias más notables:
- Las cookies sin encabezado de SameSite se tratan como
SameSite=Laxde manera predeterminada. -
SameSite=Nonedebe usarse para permitir el uso de cookies entre sitios. - Las cookies que declaran
SameSite=Nonetambién deben marcarse comoSecure. - Las aplicaciones que usan
<iframe>pueden experimentar problemas con las cookies desameSite=LaxosameSite=Strictporque<iframe>se considera en escenarios entre sitios. - El valor
SameSite=Noneno está permitido por el estándar de 2016 y hace que algunas implementaciones traten esas cookies comoSameSite=Strict. Consulte Compatibilidad con navegadores antiguos en este documento.
La configuración de SameSite=Lax funciona para la mayoría de las cookies de la aplicación. Algunas formas de autenticación como OpenID Connect (OIDC) y WS-Federation usan de manera predeterminada redireccionamientos basados en POST. Las redirecciones basadas en POST desencadenan las protecciones del explorador de SameSite, por lo que SameSite está deshabilitado para estos componentes. La mayoría de los inicios de sesión de OAuth no se ven afectados debido a las diferencias en la forma en que fluye la solicitud.
Cada componente de ASP.NET Core que emite cookies debe decidir si SameSite es adecuado.
SameSite e Identidad
ASP.NET Core Identity no se ve afectado en gran medida por las cookies de SameSite, excepto en escenarios avanzados como la integración de IFrames o OpenIdConnect.
Al usar Identity, no agregue ningún proveedor de cookies ni llame a services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme), Identity se encarga de eso.
Código de ejemplo de prueba de SameSite
El ejemplo siguiente se puede descargar y probar:
| Sample | Document |
|---|---|
| Razor Pages | ASP.NET Core ejemplo de cookie SameSite de páginas de Razor 3.1 |
Compatibilidad de .NET con el atributo SameSite
.NET admite el estándar de borrador de 2019 para SameSite. Los desarrolladores pueden controlar mediante programación el valor del atributo sameSite mediante la propiedad HttpCookie.SameSite. Al establecer la propiedad SameSite en Strict, Lax o None, esos valores se escriben en la red junto con la cookie. Establecer en SameSiteMode.Unspecified indica que no se debe enviar el sameSite con la 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 con SameSite
HttpContext.Response.Cookies.Append tiene Unspecified como valor predeterminado, lo que significa que no se ha agregado ningún atributo SameSite a la cookie y el cliente usará su comportamiento predeterminado (Lax para nuevos exploradores, None para los antiguos). En el código siguiente se muestra cómo cambiar el valor sameSite de cookie a SameSiteMode.Lax:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Todos los componentes de ASP.NET Core que emiten cookies anulan los valores predeterminados anteriores con la configuración adecuada para sus escenarios. Los valores predeterminados anteriores sobrescritos no han cambiado.
ASP.NET Core 3.1 o posterior proporciona la siguiente compatibilidad con SameSite:
- Vuelve a definir el comportamiento de
SameSiteMode.Nonepara emitirSameSite=None - Agrega un nuevo valor
SameSiteMode.Unspecifiedpara omitir el atributo SameSite. - Todas las API de cookies tienen como valor predeterminado
Unspecified. Algunos componentes que usan cookies establecen valores más específicos para sus escenarios. Consulte la tabla anterior para obtener ejemplos.
En ASP.NET Core 3.0 o posterior se cambiaron los valores predeterminados de SameSite para evitar conflictos con valores predeterminados de cliente incoherentes. Las siguientes API han cambiado el valor predeterminado de SameSiteMode.Lax a -1 para evitar la emisión de un atributo SameSite para estas cookies:
- CookieOptions usado con HttpContext.Response.Cookies.Append
-
CookieBuilder utilizado como factoría de
CookieOptions - CookiePolicyOptions.MinimumSameSitePolicy
Historia y cambios
La compatibilidad con SameSite se implementó por primera vez en ASP.NET Core en la versión 2.0 con el estándar de borrador de 2016. El estándar de 2016 era opcional. ASP.NET Core se habilitó estableciendo varias cookies en Lax de manera predeterminada. Después de encontrar varios problemas con la autenticación, se deshabilitó la mayoría del uso de SameSite.
Los parches se emitieron en noviembre de 2019 para actualizar del estándar de 2016 al estándar de 2019. El borrador de 2019 de la especificación SameSite:
- No es retrocompatible con el borrador de 2016. Para más información, vea Compatibilidad con exploradores más antiguos en este documento.
- especifica que las cookies se tratan como
SameSite=Laxde manera predeterminada; - Especifica que las cookies que afirman explícitamente
SameSite=Nonepara habilitar el envío entre sitios deben estar marcadas comoSecure.Nonees una nueva entrada para excluirse. - Es compatible con los parches emitidos para ASP.NET Core 2.1, 2.2 y 3.0. ASP.NET Core 3.1 o posterior tiene compatibilidad adicional con SameSite.
- Está previsto que Chrome lo habilite de manera predeterminada en febrero de 2020. Los navegadores empezaron a pasar a este estándar en 2019.
API afectadas por el cambio del estándar de borrador de SameSite de 2016 al estándar de borrador de SameSite de 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Admitir navegadores antiguos
El estándar SameSite de 2016 obligaba a tratar los valores desconocidos como el valor SameSite=Strict. Las aplicaciones a las que se accede desde exploradores antiguos que admiten el estándar SameSite de 2016 pueden dejar de funcionar cuando obtienen una propiedad SameSite con un valor de None. Las aplicaciones web deben implementar la detección de navegadores si pretenden ser compatibles con navegadores antiguos. ASP.NET Core no implementa la detección del explorador porque los valores de User-Agents son muy volátiles y cambian con frecuencia. Un punto de extensión en Microsoft.AspNetCore.CookiePolicy permite conectar la lógica específica de User-Agent.
En Program.cs, agrega código que llame a UseCookiePolicy antes de llamar a UseAuthentication o a cualquier método que escriba 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();
En Program.cs, agregue código similar al código resaltado siguiente:
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();
En el ejemplo anterior, MyUserAgentDetectionLib.DisallowsSameSiteNone es una biblioteca proporcionada por el usuario que detecta si el agente de usuario no admite SameSite None:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
El siguiente código muestra un método DisallowsSameSiteNone de ejemplo:
Warning
El código siguiente es solo para demostración:
- No debería considerarse completo.
- No se mantiene ni tiene soporte.
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;
}
Aplicaciones de prueba para problemas de SameSite
Las aplicaciones que interactúan con sitios remotos, por ejemplo mediante inicio de sesión de terceros, necesitan:
- Probar la interacción en varios navegadores.
- Aplica la detección y mitigación de navegador de CookiePolicy tratada en este documento.
Probar las aplicaciones web usando una versión cliente que pueda activar el nuevo comportamiento de SameSite. Chrome, Firefox y Chromium Edge tienen nuevos indicadores de función de activación voluntaria que se pueden usar para las pruebas. Una vez que su aplicación haya aplicado las revisiones de SameSite, pruébela con versiones de cliente anteriores, especialmente Safari. Para más información, vea Compatibilidad con exploradores más antiguos en este documento.
Prueba con Chrome
Chrome 78+ proporciona resultados engañosos porque tiene una mitigación temporal en su lugar. La mitigación temporal de Chrome 78+ admite cookies de menos de dos minutos de antigüedad. Chrome 76 o 77 con las marcas de prueba adecuadas habilitadas proporciona resultados más precisos. Para probar el nuevo comportamiento de SameSite, cambie el conmutador chrome://flags/#same-site-by-default-cookies a Habilitado. Se ha informado de que las versiones más antiguas de Chrome (75 e inferiores) fallan con la nueva configuración de None. Consulte Compatibilidad con exploradores más antiguos en este documento.
Google no hace que las versiones de Chrome anteriores estén disponibles. Siga las instrucciones que aparecen en Descargar Chromium para probar versiones anteriores de Chrome. No descargue Chrome desde los vínculos proporcionados mediante la búsqueda de versiones anteriores de Chrome.
A partir de la versión de Canary 80.0.3975.0, la mitigación temporal Lax+POST se puede deshabilitar con fines de prueba con la nueva marca --enable-features=SameSiteDefaultChecksMethodRigorously para permitir la prueba de sitios y servicios en el estado final de la característica en la que se ha quitado la mitigación. Para más información, consulte las Actualizaciones de SameSite de The Chromium Projects
Prueba con Safari
Safari 12 ha aplicado estrictamente el proyecto anterior y falla cuando el nuevo valor de None se encuentra en una cookie. Se evita None a través del código de detección del explorador Compatibilidad con exploradores más antiguos en este documento. Pruebe los inicios de sesión al estilo de SO basados en Safari 12, Safari 13 y WebKit mediante MSAL, ADAL o cualquier biblioteca que esté usando. El problema depende de la versión del sistema operativo subyacente. Se sabe que OSX Mojave (10.14) e iOS 12 tienen problemas de compatibilidad con el nuevo comportamiento de SameSite. Actualizar el sistema operativo a OSX Catalina (10.15) o iOS 13 soluciona el problema. Safari no tiene actualmente una opción de activación voluntaria para probar el comportamiento de la nueva especificación.
Prueba con Firefox
La compatibilidad de Firefox con el nuevo estándar puede probarse en la versión 68+ accediendo a la página about:config con la feature flag network.cookie.sameSite.laxByDefault. No ha habido informes de problemas de compatibilidad con versiones anteriores de Firefox.
Prueba con el explorador Edge
Edge admite el antiguo estándar de SameSite. La versión 44 de Edge no tiene problemas de compatibilidad conocidos con el nuevo estándar.
Prueba con Edge (Chromium)
Las marcas SameSite se establecen en la página edge://flags/#same-site-by-default-cookies. No se detectaron problemas de compatibilidad con Edge Chromium.
Prueba con Electron
Las versiones de Electron incluyen versiones anteriores de Chromium. Por ejemplo, la versión de Electron empleada por Teams es Chromium 66, que exhibe el comportamiento anterior. Debe llevar a cabo sus propias pruebas de compatibilidad con la versión de Electron que utilice su producto. Consulte Compatibilidad con exploradores más antiguos en la sección siguiente.
Recursos adicionales
- Blog de Chromium: Desarrolladores: Prepárense para la nueva configuración de cookies SameSite=None; segura
- Cookies de SameSite explicados
- Parches de noviembre de 2019
| Sample | Document |
|---|---|
| Razor Pages | ASP.NET Core ejemplo de cookie SameSite de Razor Pages 3.1 |
El ejemplo siguiente se puede descargar y probar:
| Sample | Document |
|---|---|
| Razor Pages | ASP.NET Core ejemplo de cookie SameSite de Razor Pages 3.1 |
Compatibilidad de .NET Core con el atributo sameSite
.NET Core 3.1 o posterior admite el estándar de borrador de 2019 para SameSite. Los desarrolladores pueden controlar mediante programación el valor del atributo sameSite mediante la propiedad HttpCookie.SameSite. Si se establece la SameSite propiedad en Strict, Lax o None, esos valores se escriben en la red con la cookie. Establecerlo igual a (SameSiteMode)(-1) indica que no se debe incluir ningún atributo sameSite con la cookie en la solicitud de red.
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);
.NET Core 3.1 o posterior admiten los valores actualizados de SameSite y agregan un valor adicional a la enumeración SameSiteMode.Unspecified en la enumeración SameSiteMode.
Este nuevo valor indica que no se debe enviar el sameSite con la cookie.
Uso de API con SameSite
HttpContext.Response.Cookies.Append tiene Unspecified como valor predeterminado, lo que significa que no se ha agregado ningún atributo SameSite a la cookie y el cliente usará su comportamiento predeterminado (Lax para nuevos exploradores, None para los antiguos). En el código siguiente se muestra cómo cambiar el valor sameSite de cookie a SameSiteMode.Lax:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Todos los componentes de ASP.NET Core que emiten cookies sustituyen los valores predeterminados anteriores con la configuración adecuada para sus escenarios. Los valores predeterminados anteriores sobrescritos no han cambiado.
ASP.NET Core 3.1 o posterior proporciona la siguiente compatibilidad con SameSite:
- Vuelve a definir el comportamiento de
SameSiteMode.Nonepara emitirSameSite=None - Agrega un nuevo valor
SameSiteMode.Unspecifiedpara omitir el atributo SameSite. - Todas las API de cookies tienen como valor predeterminado
Unspecified. Algunos componentes que usan cookies establecen valores más específicos para sus escenarios. Consulte la tabla anterior para obtener ejemplos.
En ASP.NET Core 3.0 o posterior se cambiaron los valores predeterminados de SameSite para evitar conflictos con valores predeterminados de cliente incoherentes. Las siguientes API han cambiado el valor predeterminado de SameSiteMode.Lax a -1 para evitar la emisión de un atributo SameSite para estas cookies:
- CookieOptions usado con HttpContext.Response.Cookies.Append
-
CookieBuilder utilizado como factoría para
CookieOptions - CookiePolicyOptions.MinimumSameSitePolicy
Historia y cambios
La compatibilidad con SameSite se implementó por primera vez en ASP.NET Core en la versión 2.0 con el estándar de borrador de 2016. El estándar de 2016 era de adopción voluntaria. ASP.NET Core se habilitó estableciendo varias cookies en Lax de manera predeterminada. Después de encontrar varios problemas con la autenticación, se deshabilitó la mayoría del uso de SameSite.
Los parches se emitieron en noviembre de 2019 para actualizar del estándar de 2016 al estándar de 2019. El borrador de 2019 de la especificación SameSite:
- No es retrocompatible con el borrador de 2016. Para más información, vea Compatibilidad con exploradores más antiguos en este documento.
- Especifica que las cookies se tratan como
SameSite=Laxde manera predeterminada. - especifica que las cookies que afirman explícitamente
SameSite=Nonepara habilitar el envío entre sitios deben estar marcadas comoSecure.Nonees una nueva entrada para darse de baja. - Recibe soporte mediante los parches emitidos para ASP.NET Core 2.1, 2.2 y 3.0. ASP.NET Core 3.1 tiene compatibilidad adicional con SameSite.
- Está previsto que Chrome lo habilite de manera predeterminada en febrero de 2020. Los navegadores empezaron a adoptar este estándar en 2019.
las API afectadas por el cambio del estándar de borrador de SameSite de 2016 al estándar de borrador de SameSite de 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Compatibilidad con exploradores más antiguos
El estándar de SameSite de 2016 obligaba a tratar los valores desconocidos como valores SameSite=Strict. Las aplicaciones a las que se accede desde exploradores antiguos que admiten el estándar de SameSite de 2016 pueden interrumpirse cuando obtienen una propiedad de SameSite con un valor de None. Las aplicaciones web deben implementar la detección de navegadores si pretenden ser compatibles con navegadores antiguos. ASP.NET Core no implementa la detección del explorador porque los valores de User-Agents son muy volátiles y cambian con frecuencia. Un punto de extensión en Microsoft.AspNetCore.CookiePolicy permite conectar la lógica específica de User-Agent.
En Startup.Configure, agrega código que llame a UseCookiePolicy antes de llamar a UseAuthentication o a cualquier método que escriba 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();
});
}
En Startup.ConfigureServices, agregue código similar al siguiente:
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;
}
}
}
En el ejemplo anterior, MyUserAgentDetectionLib.DisallowsSameSiteNone es una biblioteca proporcionada por el usuario que detecta si el agente de usuario no admite None de SameSite:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
El siguiente código muestra un método DisallowsSameSiteNone de ejemplo:
Warning
El código siguiente es solo para demostración:
- No debería considerarse completo.
- No se mantiene ni se admite.
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;
}
Aplicaciones de prueba para problemas de SameSite
Las aplicaciones que interactúan con sitios remotos, por ejemplo mediante inicio de sesión de terceros, necesitan:
- Probar la interacción en varios navegadores.
- Aplica la CookiePolicy browser detection and mitigation tratada en este documento.
Probar las aplicaciones web usando una versión cliente que pueda activar el nuevo comportamiento de SameSite. Chrome, Firefox y Chromium Edge tienen nuevos indicadores de función de activación voluntaria que se pueden usar para las pruebas. Una vez que la aplicación aplique las revisiones de SameSite, pruébela con versiones de cliente anteriores, especialmente Safari. Para más información, vea Compatibilidad con exploradores más antiguos en este documento.
Prueba con Chrome
Chrome 78+ proporciona resultados engañosos porque aplica una mitigación temporal. La mitigación temporal de Chrome 78+ admite cookies de menos de dos minutos de antigüedad. Chrome 76 o 77 con las marcas de prueba adecuadas habilitadas proporciona resultados más precisos. Para probar el nuevo comportamiento, cambie el conmutador de comportamiento SameSite chrome://flags/#same-site-by-default-cookies a Habilitado. Se ha informado de que las versiones más antiguas de Chrome (75 e inferiores) fallan con la nueva configuración de None. Consulte Compatibilidad con navegadores más antiguos en este documento.
Google no hace que las versiones de Chrome anteriores estén disponibles. Siga las instrucciones que aparecen en Descargar Chromium para probar versiones anteriores de Chrome. No descargue Chrome desde los enlaces obtenidos al buscar versiones anteriores de Chrome.
A partir de la versión de Canary 80.0.3975.0, la mitigación temporal Lax+POST se puede deshabilitar con fines de prueba con la nueva marca --enable-features=SameSiteDefaultChecksMethodRigorously para permitir la prueba de sitios y servicios en el estado final de la característica en la que se ha quitado la mitigación. Para más información, consulte las Actualizaciones de SameSite de The Chromium Projects
Prueba con Safari
Safari 12 ha aplicado estrictamente el proyecto anterior y falla cuando el nuevo valor de None se encuentra en una cookie.
None se evita a través del código de detección del explorador Compatibilidad con navegadores antiguos en este documento. Pruebe los inicios de sesión de tipo SO basados en Safari 12, Safari 13 y WebKit mediante MSAL, ADAL o cualquier biblioteca que esté usando. El problema depende de la versión del sistema operativo subyacente. Se sabe que OSX Mojave (10.14) e iOS 12 tienen problemas de compatibilidad con el nuevo comportamiento de SameSite. Actualizar el sistema operativo a OSX Catalina (10.15) o iOS 13 soluciona el problema. Safari no tiene actualmente un indicador de activación voluntaria para probar el comportamiento de la nueva especificación.
Prueba con Firefox
La compatibilidad de Firefox con el nuevo estándar puede probarse en la versión 68+ activándola en la página about:config con la marca de características network.cookie.sameSite.laxByDefault. No ha habido informes de problemas de compatibilidad con versiones anteriores de Firefox.
Prueba con el explorador Edge
Edge admite el antiguo estándar de SameSite. La versión 44 de Edge no tiene problemas de compatibilidad conocidos con el nuevo estándar.
Prueba con Edge (Chromium)
Las marcas de SameSite se establecen en la página edge://flags/#same-site-by-default-cookies. No se detectaron problemas de compatibilidad con Edge Chromium.
Prueba con Electron
Las versiones de Electron incluyen versiones anteriores de Chromium. Por ejemplo, la versión de Electron empleada por Teams es Chromium 66, que exhibe el comportamiento anterior. Debe llevar a cabo sus propias pruebas de compatibilidad con la versión de Electron que utilice su producto. Consulte Compatibilidad con exploradores más antiguos en la sección siguiente.
Recursos adicionales
- Blog de Chromium: Desarrolladores: Prepárense para la nueva configuración de cookies SameSite=None; segura
- Explicación de las cookies SameSite
- Parches de noviembre de 2019
| Sample | Document |
|---|---|
| Razor Pages | ASP.NET Core ejemplo de cookie SameSite de páginas de Razor 3.1 |
Los ejemplos siguientes se pueden descargar y probar:
| Sample | Document |
|---|---|
| MVC | Ejemplo de cookie de SameSite de ASP.NET Core 2.1 MVC |
| Razor Pages | ASP.NET Core 2.1 Ejemplo de cookie de Razor Pages SameSite |
Cambios de comportamiento del parche de diciembre
El cambio de comportamiento específico para .NET Framework y .NET Core 2.1 es cómo la propiedad SameSite interpreta el valor None. Antes del parche, un valor de None significa "No emitir el atributo en absoluto", después del parche significa "Emitir el atributo con un valor de None". Después del parche, un valor SameSite de (SameSiteMode)(-1) hace que el atributo no se emita.
El valor predeterminado de SameSite para la autenticación de formularios y las cookies de estado de sesión se cambió de None a Lax.
Uso de API con SameSite
HttpContext.Response.Cookies.Append tiene Unspecified como valor predeterminado, lo que significa que no se ha agregado ningún atributo SameSite a la cookie y el cliente usará su comportamiento predeterminado (Lax para nuevos exploradores, None para los antiguos). En el código siguiente se muestra cómo cambiar el valor sameSite de cookie a SameSiteMode.Lax:
HttpContext.Response.Cookies.Append(
"name", "value",
new CookieOptions() { SameSite = SameSiteMode.Lax });
Todos los componentes de ASP.NET Core que emiten cookies sustituyen los valores predeterminados anteriores con la configuración adecuada para sus escenarios. Los valores predeterminados anteriores que se han sobrescrito no han cambiado.
Historia y cambios
La compatibilidad con SameSite se implementó por primera vez en ASP.NET Core en la versión 2.0 con el estándar de borrador de 2016. El estándar de 2016 era opcional. ASP.NET Core se habilitó estableciendo varias cookies de forma predeterminada en Lax. Después de encontrar varios problemas con la autenticación, se deshabilitó la mayoría del uso de SameSite.
Los parches se emitieron en noviembre de 2019 para actualizar del estándar de 2016 al estándar de 2019. El borrador de 2019 de la especificación SameSite:
- No es retrocompatible con el borrador de 2016. Para más información, consulte Compatibilidad con navegadores antiguos en este documento.
- especifica que las cookies se tratan como
SameSite=Laxde manera predeterminada; - especifica que las cookies que afirman explícitamente
SameSite=Nonepara habilitar el envío entre sitios deben estar marcadas comoSecure.Nonees una nueva entrada para excluirse. - Cuenta con soporte mediante los parches emitidos para ASP.NET Core 2.1, 2.2 y 3.0. ASP.NET Core 3.1 tiene compatibilidad adicional con SameSite.
- Está previsto que Chrome lo habilite de manera predeterminada en febrero de 2020. Los navegadores empezaron a pasar a este estándar en 2019.
Las API afectadas por el cambio del estándar de borrador de SameSite de 2016 al estándar de borrador de SameSite de 2019
- Http.SameSiteMode
- CookieOptions.SameSite
- CookieBuilder.SameSite
- CookiePolicyOptions.MinimumSameSitePolicy
- Microsoft.Net.Http.Headers.SameSiteMode
- Microsoft.Net.Http.Headers.SetCookieHeaderValue.SameSite
Compatibilidad con navegadores antiguos
El estándar de SameSite de 2016 obligaba a tratar los valores desconocidos como valores SameSite=Strict. Las aplicaciones a las que se accede desde exploradores antiguos que admiten el estándar de SameSite de 2016 pueden interrumpirse cuando obtienen una propiedad de SameSite con un valor de None. Las aplicaciones web deben implementar la detección de navegadores si pretenden ser compatibles con navegadores antiguos. ASP.NET Core no implementa la detección del explorador porque los valores de User-Agents son muy volátiles y cambian con frecuencia. Un punto de extensión en Microsoft.AspNetCore.CookiePolicy permite incorporar lógica específica del User-Agent.
En Startup.Configure, agrega código que llame a UseCookiePolicy antes de llamar a UseAuthentication o a cualquier método que escriba 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();
});
}
En Startup.ConfigureServices, agregue código similar al siguiente:
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);
}
}
}
En el ejemplo anterior, MyUserAgentDetectionLib.DisallowsSameSiteNone es una biblioteca proporcionada por el usuario que detecta si el agente de usuario no admite SameSite None:
if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
options.SameSite = SameSiteMode.Unspecified;
}
El siguiente código muestra un método DisallowsSameSiteNone de ejemplo:
Warning
El código siguiente es solo para demostración:
- No debería considerarse completo.
- No se mantiene ni tiene soporte.
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;
}
Probar aplicaciones para problemas de SameSite
Las aplicaciones que interactúan con sitios remotos, por ejemplo mediante inicio de sesión de terceros, necesitan:
- Probar la interacción en varios navegadores.
- Aplica la detección y mitigación de CookiePolicy en el navegador tratada en este documento.
Probar las aplicaciones web usando una versión cliente que pueda habilitar el nuevo comportamiento de SameSite. Chrome, Firefox y Chromium Edge tienen nuevas flags de función de activación voluntaria que se pueden usar para las pruebas. Una vez que su aplicación aplique las revisiones de SameSite, pruébela con versiones de cliente anteriores, especialmente Safari. Para más información, vea Compatibilidad con exploradores más antiguos en este documento.
Prueba con Chrome
Chrome 78+ proporciona resultados engañosos porque cuenta con una mitigación temporal. La mitigación temporal de Chrome 78+ admite cookies de menos de dos minutos de antigüedad. Chrome 76 o 77 con las marcas de prueba adecuadas habilitadas proporciona resultados más precisos. Para probar el nuevo conmutador del comportamiento SameSite, cambie chrome://flags/#same-site-by-default-cookies a Habilitado. Se ha informado de que las versiones más antiguas de Chrome (75 e inferiores) fallan con la nueva configuración de None. Consulte Compatibilidad con exploradores más antiguos en este documento.
Google no hace que las versiones de Chrome anteriores estén disponibles. Siga las instrucciones que aparecen en Descargar Chromium para probar versiones anteriores de Chrome. No descargue Chrome desde enlaces encontrados al buscar versiones anteriores de Chrome.
A partir de la versión de Canary 80.0.3975.0, la mitigación temporal Lax+POST se puede deshabilitar con fines de prueba con la nueva marca --enable-features=SameSiteDefaultChecksMethodRigorously para permitir la prueba de sitios y servicios en el estado final de la característica en la que se ha quitado la mitigación. Para más información, consulte las Actualizaciones de SameSite de The Chromium Projects
Prueba con Safari
Safari 12 ha aplicado estrictamente el proyecto anterior y falla cuando el nuevo valor de None se encuentra en una cookie.
None se evita a través del código de detección del explorador Compatibilidad con navegadores antiguos en este documento. Pruebe los inicios de sesión de tipo SO basados en Safari 12, Safari 13 y WebKit mediante MSAL, ADAL o cualquier biblioteca que esté usando. El problema depende de la versión del sistema operativo subyacente. Se sabe que OSX Mojave (10.14) e iOS 12 tienen problemas de compatibilidad con el nuevo comportamiento de SameSite. Actualizar el sistema operativo a OSX Catalina (10.15) o iOS 13 soluciona el problema. Safari no tiene actualmente una opción de activación voluntaria para probar el comportamiento de la nueva especificación.
Prueba con Firefox
La compatibilidad de Firefox con el nuevo estándar puede probarse en la versión 68+ activando la marca de características network.cookie.sameSite.laxByDefault en la página about:config. No ha habido informes de problemas de compatibilidad con versiones anteriores de Firefox.
Prueba con el explorador Edge
Edge admite el antiguo estándar de SameSite. La versión 44 de Edge no tiene problemas de compatibilidad conocidos con el nuevo estándar.
Prueba con Edge (Chromium)
Las marcas de SameSite se establecen en la página edge://flags/#same-site-by-default-cookies. No se detectaron problemas de compatibilidad con Edge Chromium.
Prueba con Electron
Las versiones de Electron incluyen versiones anteriores de Chromium. Por ejemplo, la versión de Electron empleada por Teams es Chromium 66, que exhibe el comportamiento anterior. Debe llevar a cabo sus propias pruebas de compatibilidad con la versión de Electron que utilice su producto. Consulte Compatibilidad con exploradores más antiguos en la sección siguiente.
Recursos adicionales
- Blog de Chromium: Desarrolladores: Prepárense para la nueva configuración de cookies SameSite=None; segura
- Explicación de las cookies SameSite
- Parches de noviembre de 2019
| Sample | Document |
|---|---|
| MVC | Ejemplo de cookie de SameSite de ASP.NET Core 2.1 MVC |
| Razor Pages | ASP.NET Core 2.1 Ejemplo de cookie de Razor Pages SameSite |