On this page

Skip to content

Configuring SameSite Cookies in ASP.NET

TLDR

  • The SameSite attribute is used to restrict third-party cookies to defend against CSRF attacks.
  • There are three SameSite values: None (sent with all requests, requires Secure), Lax (default value, sent only in first-party or link-initiated requests), and Strict (sent only in first-party requests).
  • In ASP.NET Core, global configuration can be managed via CookiePolicyOptions, and issues with poor None support in older browsers must be handled.
  • ASP.NET Framework 4.7.2 and above support SameSite configuration; Session state requires additional configuration via <sessionState>.
  • Browser implementations vary significantly; it is recommended to perform compatibility checks based on the User-Agent.

Core Concepts of SameSite Cookies

SameSite Cookies is a standard established by the IETF, designed to restrict the sending of third-party cookies to defend against Cross-Site Request Forgery (CSRF) attacks.

Explanation of SameSite Attribute Values

When you might encounter this issue: When you need to determine whether a cookie should be sent with cross-site requests.

  • None: The cookie will be sent in all request scenarios; it must be paired with the Secure attribute in modern environments.
  • Lax: The default value for modern browsers; sent only in first-party contexts or when the user navigates to the original site via a link.
  • Strict: The cookie will only be sent in first-party context requests.

Request Support in Lax Mode

When you might encounter this issue: When an application relies on cookies for login authentication, and users arrive via links from external websites.

Request MethodCan Cookies be Obtained?
Link (<a>)O
Form GetO
Form PostX
iframeX
AJAXX
ImageX

WARNING

Both "Same-Origin Policy" and "SameSite Cookies" are highly dependent on browser implementation, and behavior may differ between versions.

Configuring SameSite Cookies in ASP.NET Core

Global Configuration and Compatibility Handling

When you might encounter this issue: When you need to manage the site-wide cookie policy uniformly and ensure that older browsers do not malfunction due to lack of support for None.

Configure CookiePolicyOptions in Program.cs and use the OnAppendCookie interceptor to handle older browsers:

csharp
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 (DisallowsSameSiteNone(userAgent)) {
            options.SameSite = SameSiteMode.Unspecified;
        }
    }
}

// ...other code...

app.UseCookiePolicy(); // Must be placed before UseAuthorization

When you might encounter this issue: When a specific cookie requires a different SameSite setting than the global policy.

csharp
Response.Cookies.Append("name", "value", new CookieOptions() { SameSite = SameSiteMode.Lax });

TIP

When SameSiteMode is not set or is specified as Unspecified, the browser will determine the behavior itself.

Configuring SameSite Cookies in ASP.NET Framework

Setting Default Values and Session

When you might encounter this issue: In environments with Framework 4.7.2 or higher, you need to set the global default cookie behavior.

Configure in Web.config:

xml
<configuration>
  <system.web>
    <!-- If an individual cookie is not set, this will be used as the default -->
    <httpCookies sameSite="Lax"></httpCookies>
    <!-- Session requires additional configuration -->
    <sessionState cookieSameSite="Lax"></sessionState>
  </system.web>
</configuration>

Compatibility Handling for Older Browsers

When you might encounter this issue: In a Framework environment, you need to dynamically correct cookies for older browsers that do not support None.

Intercept the response headers in Global.asax.cs:

csharp
protected void Application_BeginRequest(object sender, EventArgs e) {
    HttpApplication application = sender as HttpApplication;
    if (application != null) {
        var userAgent = application.Context.Request.UserAgent;
        if (DisallowsSameSiteNone(userAgent)) {
            HttpContext.Current.Response.AddOnSendingHeaders(context => {
                var cookies = context.Response.Cookies;
                for (var i = 0; i < cookies.Count; i++) {
                    var cookie = cookies[i];
                    if (cookie.SameSite == SameSiteMode.None) {
                        cookie.SameSite = (SameSiteMode)(-1); // Unspecified
                    }
                }
            });
        }
    }
}

WARNING

When testing the Same-Site behavior of ASP.NET_SessionId, it is recommended to use Incognito mode to avoid interference from previous browsing history.

Change Log

  • 2022-10-26 Initial document created.