How To Correctly Delete Your SameSite Cookies In Chrome (80+)

In my last article I explained how the changes in Chrome 80 (February 2020) can break your existing web sites or web applications, because SameSite cookies will be treated differently. In that post I focused on how to correctly set your cookies and how to mitigate incompatibilities between different browsers, as certain Safari versions don't work correctly with the new way that Chrome enforces.

In diesem Artikel:

Sebastian Gingter ist Consultant und „Erklärbär“ bei Thinktecture. Seine Spezialgebiete sind Backend-Systeme mit .NET Core und IdentityServer.

Update: If you want all details about what SameSite Cookies actually are and how they really work, I added a detailed post about that, too.

There is, however, an additional problem you can encounter.

Why doesn't Chrome delete my SameSite=None cookies?

In the new specification Google defines that in order to set a Cookie with SameSite=None, you also have to set the Secure flag.

While the current specification for cookies only describes that in order to delete a cookie, you set a new cookie with an expiry date in the past, it does specifically not require the new cookie (that will overwrite the old one) to set all flags like the original cookie.

With the changes that will be shipped in Chrome 80, this will alter this behavior, too: In order to delete a SameSite=None cookie, the replacement cookie with the expiry date in the past also needs to have the Secure flag set. If that is not the case, the cookie won’t be deleted (as in: the replacement cookie won’t be accepted by Chrome).

However, besides that the cookie should be deleted correctly, anyways. So the way to go is to pass CookieOptions that have set Secure to true when deleting the cookie like so:

					Response.Cookies.Delete("CookieName", new CookieOptions()
   Secure = true,

This will fix the deletion issue for that cookie. But again….

But my session stays active: The session cookie still isn't deleted!

Yes. There is another issue with that: The ASP.NET Core Authentication cookie is handled a bit differently and is managed by a CookieManager. Unfortunately, since the old spec did not require the secure flag, the code of the CookieManager in the .NET Core Framework (and also in .NET Full Framework) simply does not copy it over to the actual Cookies.Delete() call. Bummer.

If you don’t persist and manage your session on the server, and then rely on actually deleting the session cookie, it will simply stay there and your users will stay signed in into your website / application although they explicitly wanted to sign out.

Note: I strongly encourage you to handle your sessions on the server, so even when a session cookie accidentally stays there, the user will still be treated as signed out.

Luckily this issue should be fixed by Microsoft in .NET Core 3.x and .NET Core 2.1 in January 2020.

As this fix will likely ship in January 2020 and by then .NET Core 2.2 will already be beyond its support lifetime, Microsoft decided to not back-port that fix to .NET Core 2.2. And yes, while 2.2 actually is newer than 2.1, the 2.1 version is the one defined as long-term support (LTS) and as such only this version will get these fixes back-ported. In other words, if you are still on 2.2, you probably should update to .NET Core 3 😉.

If you are on .NET Core 2.2 and cant’t yet update to a version that will be supported for longer, or you are on 3.x or 2.1 and need that fix right now, just stay with me.

Correctly delete SameSite=None cookies in unfixed .NET Core versions

First of all, we need to back port the fix into our project. To do that, you grab the already patched ChunkingCookieManager from the ASP.NET Core repository and copy that class into your project.

Then we need to tell ASP.NET Core to use our patched CookieManager instead of the one that does not copy the Secure flag over.

To do this, we need to adjust our application startup. Locate where your authentication options are configured in your ConfigureServices method or nested calls therein.

					public void ConfigureServices(IServiceCollection services)
   // find this or similar

After you figured out where your cookie authentication is configured, adjust the code so that its going to use the patched ChunkingCookieManager instead of the default one:

					public void ConfigureServices(IServiceCollection services)
   // Adjust to this (or similar)
      .AddCookie(options =>
         // add an instance of the patched manager to the options:
         options.CookieManager = new ChunkingCookieManager();

Voilà: This will copy the secure flag also over to the delete cookie call, and the new Chrome will be persuaded to really delete your session cookie. In the last weeks we successfully implemented that in several IdentityServer projects and could make sure the cookies were really deleted.

Also make sure that your SameSite cookies are correctly set, as explained in my other post about that.


Chrome will soon (February 2020) change its default behavior of handling cookies. In the future it will require the Secure flag to be set for SameSite=None cookies. This also applies to deleting these cookies.

While setting Secure = true on the CookieOptions is enough for normal cookies, this does not apply to ASP.NET Core Authentication cookies. There is a bug that prevents the secure flag to be copied to the actual cookie deletion call.

This bug should be fixed in January 2020, but only for .NET Core 2.1 LTS and .NET Core 3.x. For .NET Core 2.2 which is out of support or until the fix is released, this article provides a workaround that ensures that the secure flag will be copied and the cookie will still be deleted when Chrome 80 ships.


Aktuelle Artikel, Screencasts, Webinare und Interviews unserer Experten für Sie

Verpassen Sie keine Inhalte zu Angular, .NET Core, Blazor, Azure und Kubernetes und melden Sie sich zu unserem kostenlosen monatlichen Dev-Newsletter an.

Newsletter Anmeldung
Diese Artikel könnten Sie interessieren
Database Access with Sessions

Data Access in .NET Native AOT with Sessions

.NET 8 brings Native AOT to ASP.NET Core, but many frameworks and libraries rely on unbound reflection internally and thus cannot support this scenario yet. This is true for ORMs, too: EF Core and Dapper will only bring full support for Native AOT in later releases. In this post, we will implement a database access layer with Sessions using the Humble Object pattern to get a similar developer experience. We will use Npgsql as a plain ADO.NET provider targeting PostgreSQL.
Old computer with native code

Native AOT with ASP.NET Core – Overview

Originally introduced in .NET 7, Native AOT can be used with ASP.NET Core in the upcoming .NET 8 release. In this post, we look at the benefits and drawbacks from a general perspective and perform measurements to quantify the improvements on different platforms.

Optimize ASP.NET Core memory with DATAS

.NET 8 introduces a new Garbage Collector feature called DATAS for Server GC mode - let's make some benchmarks and check how it fits into the big picture.

Incremental Roslyn Source Generators: High-Level API – ForAttributeWithMetadataName – Part 8

With the version 4.3.1 of Microsoft.CodeAnalysis.* Roslyn provides a new high-level API - the method "ForAttributeWithMetadataName". Although it is just 1 method, still, it addresses one of the biggest performance issue with Source Generators.

Integrating AI Power into Your .NET Applications with the Semantic Kernel Toolkit – an Early View

With the rise of powerful AI models and services, questions come up on how to integrate those into our applications and make reasonable use of them. While other languages like Python already have popular and feature-rich libraries like LangChain, we are missing these in .NET and C#. But there is a new kid on the block that might change this situation. Welcome Semantic Kernel by Microsoft!

.NET 7 Performance: Regular Expressions – Part 2

There is this popular quote by Jamie Zawinski: Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."

In this second article of our short performance series, we want to look at the latter one of those problems.