SameSite is a 2016 extension to HTTP cookies intended to mitigate cross site request forgery (CSRF). The original design was an opt-in feature which could be used by adding a new SameSite property to cookies. It had two values, Lax and Strict. Setting the value to Lax indicated the cookie should be sent on navigation within the same site, or through GET navigation to your site from other sites. A value of Strict limited the cookie to requests which only originated from the same site. Not setting the property at all placed no restrictions on how the cookie flowed in requests. OpenIdConnect authentication operations (e.g. login, logout), and other features that send POST requests from an external site to the site requesting the operation, can use cookies for correlation and/or CSRF protection. These operations would need to opt-out of SameSite, by not setting the property at all, to ensure these cookies will be sent during their specialized request flows.
Google is now updating the standard and implementing their proposed changes in an upcoming version of Chrome. The change adds a new SameSite value, “None”, and changes the default behavior to “Lax”. This breaks OpenIdConnect logins, and potentially other features your web site may rely on, these features will have to use cookies whose SameSite property is set to a value of “None”. However browsers which adhere to the original standard and are unaware of the new value have a different behavior to browsers which use the new standard as the SameSite standard states that if a browser sees a value for SameSite it does not understand it should treat that value as “Strict”. This means your .NET website will now have to add user agent sniffing to decide whether you send the new None value, or not send the attribute at all.
.NET will issue updates to change the behavior of its SameSite attribute behavior in .NET 4.7.2 and in .NET Core 2.1 and above to reflect Google’s introduction of a new value. The updates for the .NET Framework will be available on December 10th. .NET Core updates will be available with .NET Core 3.1 starting with preview 1, in early November. .NET 3.0 and 2.1 updates will release on 19th November.
.NET Core 3.1 will contain an updated enum definition, SameSite.Unspecified which will not set the SameSite property.
The OpenIdConnect middleware for Microsoft.Owin v4.1 and .NET Core will be updated at the same time as their .NET Framework and .NET updates, however we cannot introduce the user agent sniffing code into the framework, this must be implemented in your site code. The implementation of agent sniffing will vary according to what version of ASP.NET or ASP.NET Core you are using and the browsers you wish to support.
For ASP.NET 4.7.2 with Microsoft.Owin 4.1.0 agent sniffing can be implemented using ICookieManager;
public class SameSiteCookieManager : ICookieManager
{
private readonly ICookieManager _innerManager;
public SameSiteCookieManager() : this(new CookieManager())
{
}
public SameSiteCookieManager(ICookieManager innerManager)
{
_innerManager = innerManager;
}
public void AppendResponseCookie(IOwinContext context, string key, string value,
CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.AppendResponseCookie(context, key, value, options);
}
public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
{
CheckSameSite(context, options);
_innerManager.DeleteCookie(context, key, options);
}
public string GetRequestCookie(IOwinContext context, string key)
{
return _innerManager.GetRequestCookie(context, key);
}
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None && DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
public static bool DisallowsSameSiteNone(IOwinContext context)
{
// TODO: Use your User Agent library of choice here.
var userAgent = context.Request.Headers["User-Agent"];
if (string.IsNullOrEmpty(userAgent))
{
return false;
}
return userAgent.Contains("BrokenUserAgent") ||
userAgent.Contains("BrokenUserAgent2")
}
}
And then configure OpenIdConnect settings to use the new CookieManager;
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// … Your preexisting options …
CookieManager = new SameSiteCookieManager(new SystemWebCookieManager())
});
SystemWebCookieManager will need the .NET 4.7.2 or later SameSite patch installed to work correctly.
For ASP.NET Core you should install the patches and then implement the agent sniffing code within a cookie policy. For versions prior to 3.1 replace SameSiteMode.Unspecified with (SameSiteMode)(-1).
private void CheckSameSite(HttpContext httpContext, CookieOptions options)
{
if (options.SameSite == SameSiteMode.None)
{
var userAgent = httpContext.Request.Headers["User-Agent"].ToString();
// TODO: Use your User Agent library of choice here.
if (/* UserAgent doesn’t support new behavior */)
{
// For .NET Core < 3.1 set SameSite = (SameSiteMode)(-1)
options.SameSite = SameSiteMode.Unspecified;
}
}
}
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);
});
}
public void Configure(IApplicationBuilder app)
{
app.UseCookiePolicy(); // Before UseAuthentication or anything else that writes cookies.
app.UseAuthentication();
// …
}
Under testing with the Azure Active Directory team we have found the following checks work for all the common user agents that Azure Active Directory sees that don’t understand the new value.
public static bool DisallowsSameSiteNone(string userAgent)
{
if (string.IsNullOrEmpty(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;
}
This browser list is by no means canonical and you should validate that the common browsers and other user agents your system supports behave as expected once the update is in place.
Chrome 80 is scheduled to turn on the new behavior in February or March 2020, including a temporary mitigation added in Chrome 79 Beta. If you want to test the new behavior without the mitigation use Chromium 76. Older versions of Chromium are available for download.
If you cannot update your framework versions by the time Chrome turns the new behavior in early 2020 you may be able to change your OpenIdConnect flow to a Code flow, rather than the default implicit flow that ASP.NET and ASP.NET Core uses, but this should be viewed as a temporary measure.
- For ASP.NET MVC and Microsoft.Owin support you can use the Katana GitHub repository at https://github.com/aspnet/AspNetKatana.
- For ASP.NET Core support you can use the ASP.NET Core GitHub repository at https://github.com/aspnet/AspNetCore.
- For .NET Framework support please see https://dotnet.microsoft.com/platform/support/policy/dotnet-framework
We strongly encourage you to download the updated .NET Framework and .NET Core versions when they become available in November and start planning your update before Chrome’s changes are rolled out.
January 17 Update: Azure have announced their plans for the .NET Same-Site Framework update.
This change has caused quite a few headaches for intranet applications, since many of them do not use fully qualified domain names and require configuring secure, SameSite=None cookies. For many of our customers, configuring an SSL certificate on an intranet machine and the required web.config changes proves to be challenging.
One workaround I've found is to simply have the browserset the ASP.NET_SessionID cookie directly on load. In an MVC application, it can be as simple as...
This change has caused quite a few headaches for intranet applications, since many of them do not use fully qualified domain names and require configuring secure, SameSite=None cookies. For many of our customers, configuring an SSL certificate on an intranet machine and the required web.config changes proves to be challenging.
One workaround I've found is to simply have the browser set the ASP.NET_SessionID cookie directly on load. In an MVC application, it can...
I've been tracking an issue with preview of PDF files in Google Chrome for Asp.Net based sites with Forms Authentication that seems to be the cause of the recent .Net security patch. The issue appears when the PDF is big enough to cause chunked download when previewing the PDF. Google will treat the chunked requests as cross-site requests - and thus drop any cookie with samesite set to LAX. In my opinion - this is...
I have tried the above code on asp.net 4.72 and I never see the cookie for .AspNet.ExternalCookie (the core part of how owin passes authentication to the next page) being set. I see other cookies going through the SameSiteCookieManager from both CookieAuthenticationOptions and OpenIdConnectAuthenticationOptions. It is as if that cookie is lost in a black hole of being set.
To the best of my knowledge I have updated
* owin
* .net framework
...
I...
One of the identity cookie likely needs a separate config. Please open an issue at https://github.com/aspnet/aspnetkatana with a complete Startup.cs
We share our startup code with a few different websites, so it is encapsulated in it’s own project could that be the issue?
Is there a key dll that has the samesite patch that is not part of owin that I can look for a timestamp on?
Please open an issue on github. Blog comments don’t lend themselves to trying to figure out technical questions.
https://github.com/aspnet/AspNetKatana/issues/331
We migrated from .net 4.52 to .net 4.7.2 version, our web server (IIS 8.5) is on Windows 2012 R2. We made the changes in the web.config as below to set cookieSameSite as "None", but dont see SameSite as "None" in developer tool when we check the cookie. Does it require Windows Server 2019 and latest security
patch (2019-12 Cumulative Update for .NET Framework 3.5 and 4.7.2 for Windows 10 Version 1809 for x64 (KB4533013))? This...
I think you need https://support.microsoft.com/en-us/help/4533011/kb4533011
Thanks a lot!
It does require the December update for .NET. It should be available for 2012, according to https://support.microsoft.com/en-us/help/4486081/microsoft-net-framework-4-8-for-windows-server-2012. That also has a manual download you can use.
Thanks Barry, just went through the article but it does not talk anything about chrome 80 same site issue.
This is an absolute disaster and I don't think Google nor Microsoft has yet realized the complete shit storm they just unleashed. Over the weekend I decided I would patch our web servers with the latest updates, only to find those .net updates now decided to start setting SameSite=lax by default, where before nothing was set at all. In all their wisdom the morons at Google never realized the impact the SameSite=lax has on REAL...
This is more Microsoft's fault than Google's, in my estimation. It looks like the November 2019 security update added to every dang cookie, with the promise that you can change the behavior with edits to your . Only actually, if your application is older than .NET 4.7.2, you can't, because all the various flavors of attributes are unsupported, as far as I can tell. I ended up having to install...
Support for sameSite was only introduced in .NET 4.7.2, so yes, if you’re targeting previous versions which have no support, but are runnong on .NET 4.7.2 you’re going to have problems. The long term fix here is to migrate your application to 4.7.2 or later.
We also ran into this issue today on our staging site as it seems that Chrome 79 started causing trouble. To fix it we added cookieSameSite=”None” to the forms tag nested under the authentication tag in system.web
We have IdentityServer4 with .NET Core 2.1 and followed the instructions. Updated all packages, SDK, runtime, etc. to the latest versions and made the code changes. Still didn’t get SameSite=None on our IdentityServer cookies.
In the end I found this issue: https://github.com/dotnet/aspnetcore/issues/18265. The Microsoft.Net.Http.Headers assembly was still on 2.1.1. We added a direct reference to 2.1.14 in our .csproj. This fixed the problem.
We Have an app running on 4.8. implemented the same-site fix. it works locally but when deployed to the server the user-agent is not there. so it fails.
any idea as to why? local is iisExpress and server is windows server 2016 with iis10. server also has 4.8 runtime. all owin packages are updated to 4.1..
No, that’s really weird. User Agent should always be there. Is there a reverse proxy in front of it? Might that not be passing the agent on?
We're having trouble with deploying this with an Azure Web App.
The site being deployed targets .Net 4.7.2, and the changes work when tested locally as expected.
If we decompile the System.Web.dll (downloaded through Kudu) we're seeing an older version that doesn't handle samesite cookies.
This appears to be an issue for others (with 4.7.2 despite the 4.8 topic).
https://feedback.azure.com/forums/169385-web-apps/suggestions/37566262-upgrade-app-service-with-net-4-8
Would the expectation be that Azure would have also been patched now? The timestamp on the System.Web.dll is 11/12/2019 but...
I cannot speak to Azure web apps’ timeline. But not, they haven’t rolled it out yet, I don’t know when that will be.