Bagikan melalui


Bekerja dengan cookie SameSite di ASP.NET Core

Oleh Rick Anderson

SameSite adalah standar draf IETF yang dirancang untuk memberikan perlindungan terhadap serangan pemalsuan permintaan lintas situs (CSRF). Awalnya dibuat pada tahun 2016, draf standar diperbarui pada tahun 2019. Standar yang diperbarui tidak kompatibel mundur dengan standar sebelumnya, dengan berikut ini adalah perbedaan yang paling nyata:

  • Cookie tanpa header SameSite diperlakukan sebagai SameSite=Lax secara default.
  • SameSite=None harus digunakan untuk mengizinkan penggunaan lintas situs cookie .
  • Cookie yang menegaskan SameSite=None juga harus ditandai sebagai Secure.
  • Aplikasi yang menggunakan <iframe> mungkin mengalami masalah dengan sameSite=Lax atau sameSite=Strict cookie karena <iframe> diperlakukan sebagai skenario lintas situs.
  • Nilai SameSite=None tidak diizinkan oleh standar 2016 dan menyebabkan beberapa implementasi memperlakukan cookie seperti SameSite=Strict. Lihat Mendukung browser lama dalam dokumen ini.

Pengaturan SameSite=Lax ini berfungsi untuk sebagian besar cookie aplikasi. Beberapa bentuk autentikasi seperti OpenID Connect (OIDC) dan WS-Federation default ke pengalihan berbasis POST. Pengalihan berbasis POST memicu perlindungan browser SameSite, sehingga SameSite dinonaktifkan untuk komponen ini. Sebagian besar login OAuth tidak terpengaruh karena perbedaan bagaimana permintaan mengalir.

Setiap komponen ASP.NET Core yang memancarkan cookie perlu memutuskan apakah SameSite sesuai.

SameSite dan Identity

ASP.NET Core Identity sebagian besar tidak terpengaruh oleh cookie SameSite kecuali untuk skenario lanjutan seperti IFrames atau OpenIdConnect integrasi.

Saat menggunakan Identity, jangan tambahkan penyedia atau panggilan services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)apa puncookie, Identity urus itu.

Kode sampel pengujian SameSite

Sampel berikut dapat diunduh dan diuji:

Sampel Dokumen
Halaman .NET Core Razor sampel ASP.NET Core 3.1 Razor Pages SameSite cookie

Dukungan .NET Core untuk atribut sameSite

.NET Core mendukung standar draf 2019 untuk SameSite. Pengembang dapat mengontrol nilai atribut sameSite secara terprogram menggunakan HttpCookie.SameSite properti . SameSite Mengatur properti ke Strict, Lax, atau None menghasilkan nilai-nilai yang ditulis di jaringan dengan cookie. Pengaturan ke SameSiteMode.Unspecified menunjukkan tidak ada sameSite yang harus dikirim dengan 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);
}

Penggunaan API dengan SameSite

HttpContext.Response.Cookies.Tambahkan default ke Unspecified, yang berarti tidak ada atribut SameSite yang ditambahkan ke cookie dan klien akan menggunakan perilaku defaultnya (Lax untuk browser baru, Tidak ada untuk yang lama). Kode berikut menunjukkan cara mengubah cookie nilai SameSite menjadi SameSiteMode.Lax:

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

Semua komponen ASP.NET Core yang memancarkan cookie mengambil alih default sebelumnya dengan pengaturan yang sesuai untuk skenarionya. Nilai default sebelumnya yang ditimpa tidak berubah.

Komponen cookie Default
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Otentikasi CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenIdConnectOptions.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

ASP.NET Core 3.1 dan yang lebih baru menyediakan dukungan SameSite berikut:

  • Menentukan ulang perilaku untuk memancarkan SameSiteMode.NoneSameSite=None
  • Menambahkan nilai SameSiteMode.Unspecified baru untuk menghilangkan atribut SameSite.
  • Semua API cookie default ke Unspecified. Beberapa komponen yang menggunakan cookie menetapkan nilai yang lebih spesifik untuk skenarionya. Lihat tabel di atas untuk contoh.

Di ASP.NET Core 3.0 dan yang lebih baru default SameSite diubah untuk menghindari konflik dengan default klien yang tidak konsisten. API berikut telah mengubah default dari SameSiteMode.Lax ke -1 untuk menghindari memancarkan atribut SameSite untuk cookie ini:

Riwayat dan perubahan

Dukungan SameSite pertama kali diterapkan di ASP.NET Core pada 2.0 menggunakan standar draf 2016. Standar 2016 adalah keikutsertaan. ASP.NET Core ikut serta dengan mengatur beberapa cookie ke Lax secara default. Setelah mengalami beberapa masalah dengan autentikasi, sebagian besar penggunaan SameSite dinonaktifkan.

Patch dikeluarkan pada November 2019 untuk memperbarui dari standar 2016 ke standar 2019. Draf spesifikasi SameSite 2019:

  • Tidak kompatibel dengan draf 2016. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.
  • Menentukan cookie diperlakukan sebagai SameSite=Lax secara default.
  • Menentukan cookie yang secara eksplisit menegaskan SameSite=None untuk mengaktifkan pengiriman lintas situs harus ditandai sebagai Secure. None adalah entri baru untuk memilih keluar.
  • Didukung oleh patch yang dikeluarkan untuk ASP.NET Core 2.1, 2.2, dan 3.0. ASP.NET Core 3.1 dan yang lebih baru memiliki dukungan SameSite tambahan.
  • Dijadwalkan untuk diaktifkan oleh Chrome secara default pada Feb 2020. Browser mulai beralih ke standar ini pada tahun 2019.

API yang terpengaruh oleh perubahan dari standar draf SameSite 2016 ke standar draf 2019

Mendukung browser yang lebih lama

Standar SameSite 2016 mengamanatkan bahwa nilai yang tidak diketahui harus diperlakukan sebagai SameSite=Strict nilai. Aplikasi yang diakses dari browser lama yang mendukung standar SameSite 2016 dapat rusak ketika mereka mendapatkan properti SameSite dengan nilai None. Aplikasi web harus menerapkan deteksi browser jika ingin mendukung browser yang lebih lama. ASP.NET Core tidak menerapkan deteksi browser karena nilai User-Agents sangat volatil dan sering berubah. Titik ekstensi di Microsoft.AspNetCore.CookiePolicy memungkinkan penyambungan logika spesifik Agen Pengguna.

Di Program.cs, tambahkan kode yang memanggil UseCookiePolicy sebelum memanggil UseAuthentication atau metode apa pun yang menulis cookie:

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();

Di Program.cs, tambahkan kode yang mirip dengan kode yang disorot berikut:

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();

Dalam sampel sebelumnya, MyUserAgentDetectionLib.DisallowsSameSiteNone adalah pustaka yang disediakan pengguna yang mendeteksi apakah agen pengguna tidak mendukung SameSite None:

if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
    options.SameSite = SameSiteMode.Unspecified;
}

Kode berikut menunjukkan metode sampel DisallowsSameSiteNone :

Peringatan

Kode berikut hanya untuk demonstrasi:

  • Seharusnya tidak dianggap lengkap.
  • Ini tidak dipertahankan atau didukung.
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;
}

Menguji aplikasi untuk masalah SameSite

Aplikasi yang berinteraksi dengan situs jarak jauh seperti melalui login pihak ketiga perlu:

  • Uji interaksi di beberapa browser.
  • Terapkan deteksi dan mitigasi browser CookiePolicy yang dibahas dalam dokumen ini.

Uji aplikasi web menggunakan versi klien yang dapat ikut serta dalam perilaku SameSite baru. Chrome, Firefox, dan Chromium Edge semuanya memiliki bendera fitur keikutsertaan baru yang dapat digunakan untuk pengujian. Setelah aplikasi Anda menerapkan patch SameSite, uji dengan versi klien yang lebih lama, terutama Safari. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.

Uji dengan Chrome

Chrome 78+ memberikan hasil yang menyesatkan karena memiliki mitigasi sementara. Mitigasi sementara Chrome 78+ memungkinkan cookie berumur kurang dari dua menit. Chrome 76 atau 77 dengan bendera pengujian yang sesuai diaktifkan memberikan hasil yang lebih akurat. Untuk menguji tombol perilaku chrome://flags/#same-site-by-default-cookies SameSite baru ke Diaktifkan. Chrome versi lama (75 ke bawah) dilaporkan gagal dengan pengaturan baru None . Lihat Mendukung browser lama dalam dokumen ini.

Google tidak membuat versi chrome yang lebih lama tersedia. Ikuti petunjuk di Unduh Chromium untuk menguji versi Chrome yang lebih lama. Jangan unduh Chrome dari tautan yang disediakan dengan mencari chrome versi lama.

Mulai dari versi 80.0.3975.0Canary , mitigasi sementara Lax+POST dapat dinonaktifkan untuk tujuan pengujian menggunakan bendera --enable-features=SameSiteDefaultChecksMethodRigorously baru untuk memungkinkan pengujian situs dan layanan dalam status akhir akhir fitur tempat mitigasi telah dihapus. Untuk informasi selengkapnya, lihat Pembaruan SameSite Proyek Chromium

Uji dengan Safari

Safari 12 secara ketat menerapkan draf sebelumnya dan gagal ketika nilai baru None berada dalam cookie. None dihindari melalui kode deteksi browser Mendukung browser lama dalam dokumen ini. Uji login gaya OS berbasis Safari 12, Safari 13, dan WebKit menggunakan MSAL, ADAL, atau pustaka apa pun yang Anda gunakan. Masalahnya tergantung pada versi OS yang mendasar. OSX Mojave (10.14) dan iOS 12 diketahui memiliki masalah kompatibilitas dengan perilaku SameSite baru. Meningkatkan OS ke OSX Catalina (10.15) atau iOS 13 memperbaiki masalah. Safari saat ini tidak memiliki bendera keikutsertaan untuk menguji perilaku spesifikasi baru.

Uji dengan Firefox

Dukungan Firefox untuk standar baru dapat diuji pada versi 68+ dengan memilih ikut serta di about:config halaman dengan bendera network.cookie.sameSite.laxByDefaultfitur . Belum ada laporan masalah kompatibilitas dengan versi Firefox yang lebih lama.

Uji dengan browser Edge

Edge mendukung standar SameSite lama. Edge versi 44 tidak memiliki masalah kompatibilitas yang diketahui dengan standar baru.

Uji dengan Edge (Chromium)

Bendera SameSite diatur pada edge://flags/#same-site-by-default-cookies halaman. Tidak ada masalah kompatibilitas yang ditemukan dengan Edge Chromium.

Uji dengan Electron

Electron Versi termasuk versi Chromium yang lebih lama. Misalnya, versi yang Electron digunakan oleh Teams adalah Chromium 66, yang menunjukkan perilaku yang lebih lama. Anda harus melakukan pengujian kompatibilitas Anda sendiri dengan versi penggunaan Electron produk Anda. Lihat Mendukung browser lama di bagian berikut.

Sumber Daya Tambahan:

Sampel Dokumen
Halaman .NET Core Razor sampel ASP.NET Core 3.1 Razor Pages SameSite cookie

Sampel berikut dapat diunduh dan diuji:

Sampel Dokumen
Halaman .NET Core Razor sampel ASP.NET Core 3.1 Razor Pages SameSite cookie

Dukungan .NET Core untuk atribut sameSite

.NET Core 3.1 dan yang lebih baru mendukung standar draf 2019 untuk SameSite. Pengembang dapat mengontrol nilai atribut sameSite secara terprogram menggunakan HttpCookie.SameSite properti . SameSite Mengatur properti ke Strict, Lax, atau None menghasilkan nilai-nilai yang ditulis di jaringan dengan cookie. Mengaturnya sama dengan (SameSiteMode)(-1) menunjukkan bahwa tidak ada atribut sameSite yang harus disertakan di jaringan dengan 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);

.NET Core 3.1 dan yang lebih baru mendukung nilai SameSite yang diperbarui dan menambahkan nilai enum tambahan, SameSiteMode.Unspecified ke SameSiteMode enum. Nilai baru ini menunjukkan tidak ada sameSite yang harus dikirim dengan cookie.

Penggunaan API dengan SameSite

HttpContext.Response.Cookies.Tambahkan default ke Unspecified, yang berarti tidak ada atribut SameSite yang ditambahkan ke cookie dan klien akan menggunakan perilaku defaultnya (Lax untuk browser baru, Tidak ada untuk yang lama). Kode berikut menunjukkan cara mengubah cookie nilai SameSite menjadi SameSiteMode.Lax:

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

Semua komponen ASP.NET Core yang memancarkan cookie mengambil alih default sebelumnya dengan pengaturan yang sesuai untuk skenarionya. Nilai default sebelumnya yang ditimpa tidak berubah.

Komponen cookie Default
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Otentikasi CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenIdConnectOptions.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

ASP.NET Core 3.1 dan yang lebih baru menyediakan dukungan SameSite berikut:

  • Menentukan ulang perilaku untuk memancarkan SameSiteMode.NoneSameSite=None
  • Menambahkan nilai SameSiteMode.Unspecified baru untuk menghilangkan atribut SameSite.
  • Semua API cookie default ke Unspecified. Beberapa komponen yang menggunakan cookie menetapkan nilai yang lebih spesifik untuk skenarionya. Lihat tabel di atas untuk contoh.

Di ASP.NET Core 3.0 dan yang lebih baru default SameSite diubah untuk menghindari konflik dengan default klien yang tidak konsisten. API berikut telah mengubah default dari SameSiteMode.Lax ke -1 untuk menghindari memancarkan atribut SameSite untuk cookie ini:

Riwayat dan perubahan

Dukungan SameSite pertama kali diterapkan di ASP.NET Core pada 2.0 menggunakan standar draf 2016. Standar 2016 adalah keikutsertaan. ASP.NET Core ikut serta dengan mengatur beberapa cookie ke Lax secara default. Setelah mengalami beberapa masalah dengan autentikasi, sebagian besar penggunaan SameSite dinonaktifkan.

Patch dikeluarkan pada November 2019 untuk memperbarui dari standar 2016 ke standar 2019. Draf spesifikasi SameSite 2019:

  • Tidak kompatibel dengan draf 2016. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.
  • Menentukan cookie diperlakukan sebagai SameSite=Lax secara default.
  • Menentukan cookie yang secara eksplisit menegaskan SameSite=None untuk mengaktifkan pengiriman lintas situs harus ditandai sebagai Secure. None adalah entri baru untuk memilih keluar.
  • Didukung oleh patch yang dikeluarkan untuk ASP.NET Core 2.1, 2.2, dan 3.0. ASP.NET Core 3.1 memiliki dukungan SameSite tambahan.
  • Dijadwalkan untuk diaktifkan oleh Chrome secara default pada Feb 2020. Browser mulai beralih ke standar ini pada tahun 2019.

API yang terpengaruh oleh perubahan dari standar draf SameSite 2016 ke standar draf 2019

Mendukung browser yang lebih lama

Standar SameSite 2016 mengamanatkan bahwa nilai yang tidak diketahui harus diperlakukan sebagai SameSite=Strict nilai. Aplikasi yang diakses dari browser lama yang mendukung standar SameSite 2016 dapat rusak ketika mereka mendapatkan properti SameSite dengan nilai None. Aplikasi web harus menerapkan deteksi browser jika ingin mendukung browser yang lebih lama. ASP.NET Core tidak menerapkan deteksi browser karena nilai User-Agents sangat volatil dan sering berubah. Titik ekstensi di Microsoft.AspNetCore.CookiePolicy memungkinkan penyambungan logika spesifik Agen Pengguna.

Di Startup.Configure, tambahkan kode yang memanggil UseCookiePolicy sebelum memanggil UseAuthentication atau metode apa pun yang menulis cookie:

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();
    });
}

Di Startup.ConfigureServices, tambahkan kode yang mirip dengan yang berikut ini:

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;
        }
    }
}

Dalam sampel sebelumnya, MyUserAgentDetectionLib.DisallowsSameSiteNone adalah pustaka yang disediakan pengguna yang mendeteksi apakah agen pengguna tidak mendukung SameSite None:

if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
    options.SameSite = SameSiteMode.Unspecified;
}

Kode berikut menunjukkan metode sampel DisallowsSameSiteNone :

Peringatan

Kode berikut hanya untuk demonstrasi:

  • Seharusnya tidak dianggap lengkap.
  • Ini tidak dipertahankan atau didukung.
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;
}

Menguji aplikasi untuk masalah SameSite

Aplikasi yang berinteraksi dengan situs jarak jauh seperti melalui login pihak ketiga perlu:

  • Uji interaksi di beberapa browser.
  • Terapkan deteksi dan mitigasi browser CookiePolicy yang dibahas dalam dokumen ini.

Uji aplikasi web menggunakan versi klien yang dapat ikut serta dalam perilaku SameSite baru. Chrome, Firefox, dan Chromium Edge semuanya memiliki bendera fitur keikutsertaan baru yang dapat digunakan untuk pengujian. Setelah aplikasi Anda menerapkan patch SameSite, uji dengan versi klien yang lebih lama, terutama Safari. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.

Uji dengan Chrome

Chrome 78+ memberikan hasil yang menyesatkan karena memiliki mitigasi sementara. Mitigasi sementara Chrome 78+ memungkinkan cookie berumur kurang dari dua menit. Chrome 76 atau 77 dengan bendera pengujian yang sesuai diaktifkan memberikan hasil yang lebih akurat. Untuk menguji tombol perilaku chrome://flags/#same-site-by-default-cookies SameSite baru ke Diaktifkan. Chrome versi lama (75 ke bawah) dilaporkan gagal dengan pengaturan baru None . Lihat Mendukung browser lama dalam dokumen ini.

Google tidak membuat versi chrome yang lebih lama tersedia. Ikuti petunjuk di Unduh Chromium untuk menguji versi Chrome yang lebih lama. Jangan unduh Chrome dari tautan yang disediakan dengan mencari chrome versi lama.

Mulai dari versi 80.0.3975.0Canary , mitigasi sementara Lax+POST dapat dinonaktifkan untuk tujuan pengujian menggunakan bendera --enable-features=SameSiteDefaultChecksMethodRigorously baru untuk memungkinkan pengujian situs dan layanan dalam status akhir akhir fitur tempat mitigasi telah dihapus. Untuk informasi selengkapnya, lihat Pembaruan SameSite Proyek Chromium

Uji dengan Safari

Safari 12 secara ketat menerapkan draf sebelumnya dan gagal ketika nilai baru None berada dalam cookie. None dihindari melalui kode deteksi browser Mendukung browser lama dalam dokumen ini. Uji login gaya OS berbasis Safari 12, Safari 13, dan WebKit menggunakan MSAL, ADAL, atau pustaka apa pun yang Anda gunakan. Masalahnya tergantung pada versi OS yang mendasar. OSX Mojave (10.14) dan iOS 12 diketahui memiliki masalah kompatibilitas dengan perilaku SameSite baru. Meningkatkan OS ke OSX Catalina (10.15) atau iOS 13 memperbaiki masalah. Safari saat ini tidak memiliki bendera keikutsertaan untuk menguji perilaku spesifikasi baru.

Uji dengan Firefox

Dukungan Firefox untuk standar baru dapat diuji pada versi 68+ dengan memilih ikut serta di about:config halaman dengan bendera network.cookie.sameSite.laxByDefaultfitur . Belum ada laporan masalah kompatibilitas dengan versi Firefox yang lebih lama.

Uji dengan browser Edge

Edge mendukung standar SameSite lama. Edge versi 44 tidak memiliki masalah kompatibilitas yang diketahui dengan standar baru.

Uji dengan Edge (Chromium)

Bendera SameSite diatur pada edge://flags/#same-site-by-default-cookies halaman. Tidak ada masalah kompatibilitas yang ditemukan dengan Edge Chromium.

Uji dengan Electron

Electron Versi termasuk versi Chromium yang lebih lama. Misalnya, versi yang Electron digunakan oleh Teams adalah Chromium 66, yang menunjukkan perilaku yang lebih lama. Anda harus melakukan pengujian kompatibilitas Anda sendiri dengan versi penggunaan Electron produk Anda. Lihat Mendukung browser lama di bagian berikut.

Sumber Daya Tambahan:

Sampel Dokumen
Halaman .NET Core Razor sampel ASP.NET Core 3.1 Razor Pages SameSite cookie

Sampel berikut dapat diunduh dan diuji:

Sampel Dokumen
.NET Core MVC sampel ASP.NET Core 2.1 MVC SameSite cookie
Halaman .NET Core Razor ASP.NET sampel SameSite cookie Halaman Core 2.1 Razor

Perubahan perilaku patch Desember

Perubahan perilaku khusus untuk .NET Framework dan .NET Core 2.1 adalah bagaimana SameSite properti menginterpretasikan None nilai. Sebelum patch nilai None yang dimaksudkan "Jangan keluarkan atribut sama sekali", setelah patch itu berarti "Keluarkan atribut dengan nilai None". Setelah patch, SameSite nilai (SameSiteMode)(-1) menyebabkan atribut tidak dipancarkan.

Nilai SameSite default untuk autentikasi formulir dan cookie status sesi diubah dari None ke Lax.

Penggunaan API dengan SameSite

HttpContext.Response.Cookies.Tambahkan default ke Unspecified, yang berarti tidak ada atribut SameSite yang ditambahkan ke cookie dan klien akan menggunakan perilaku defaultnya (Lax untuk browser baru, Tidak ada untuk yang lama). Kode berikut menunjukkan cara mengubah cookie nilai SameSite menjadi SameSiteMode.Lax:

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

Semua komponen ASP.NET Core yang memancarkan cookie mengambil alih default sebelumnya dengan pengaturan yang sesuai untuk skenarionya. Nilai default sebelumnya yang ditimpa tidak berubah.

Komponen cookie Default
CookieBuilder SameSite Unspecified
Session SessionOptions.Cookie Lax
CookieTempDataProvider CookieTempDataProviderOptions.Cookie Lax
IAntiforgery AntiforgeryOptions.Cookie Strict
Cookie Otentikasi CookieAuthenticationOptions.Cookie Lax
AddTwitter TwitterOptions.StateCookie Lax
RemoteAuthenticationHandler<TOptions> RemoteAuthenticationOptions.CorrelationCookie None
AddOpenIdConnect OpenIdConnectOptions.NonceCookie None
HttpContext.Response.Cookies.Append CookieOptions Unspecified

Riwayat dan perubahan

Dukungan SameSite pertama kali diterapkan di ASP.NET Core pada 2.0 menggunakan standar draf 2016. Standar 2016 adalah keikutsertaan. ASP.NET Core ikut serta dengan mengatur beberapa cookie ke Lax secara default. Setelah mengalami beberapa masalah dengan autentikasi, sebagian besar penggunaan SameSite dinonaktifkan.

Patch dikeluarkan pada November 2019 untuk memperbarui dari standar 2016 ke standar 2019. Draf spesifikasi SameSite 2019:

  • Tidak kompatibel dengan draf 2016. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.
  • Menentukan cookie diperlakukan sebagai SameSite=Lax secara default.
  • Menentukan cookie yang secara eksplisit menegaskan SameSite=None untuk mengaktifkan pengiriman lintas situs harus ditandai sebagai Secure. None adalah entri baru untuk memilih keluar.
  • Didukung oleh patch yang dikeluarkan untuk ASP.NET Core 2.1, 2.2, dan 3.0. ASP.NET Core 3.1 memiliki dukungan SameSite tambahan.
  • Dijadwalkan untuk diaktifkan oleh Chrome secara default pada Feb 2020. Browser mulai beralih ke standar ini pada tahun 2019.

API yang terpengaruh oleh perubahan dari standar draf SameSite 2016 ke standar draf 2019

Mendukung browser yang lebih lama

Standar SameSite 2016 mengamanatkan bahwa nilai yang tidak diketahui harus diperlakukan sebagai SameSite=Strict nilai. Aplikasi yang diakses dari browser lama yang mendukung standar SameSite 2016 dapat rusak ketika mereka mendapatkan properti SameSite dengan nilai None. Aplikasi web harus menerapkan deteksi browser jika ingin mendukung browser yang lebih lama. ASP.NET Core tidak menerapkan deteksi browser karena nilai User-Agents sangat volatil dan sering berubah. Titik ekstensi di Microsoft.AspNetCore.CookiePolicy memungkinkan penyambungan logika spesifik Agen Pengguna.

Di Startup.Configure, tambahkan kode yang memanggil UseCookiePolicy sebelum memanggil UseAuthentication atau metode apa pun yang menulis cookie:

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();
    });
}

Di Startup.ConfigureServices, tambahkan kode yang mirip dengan yang berikut ini:

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);
        }

    }
}

Dalam sampel sebelumnya, MyUserAgentDetectionLib.DisallowsSameSiteNone adalah pustaka yang disediakan pengguna yang mendeteksi apakah agen pengguna tidak mendukung SameSite None:

if (MyUserAgentDetectionLib.DisallowsSameSiteNone(userAgent))
{
    options.SameSite = SameSiteMode.Unspecified;
}

Kode berikut menunjukkan metode sampel DisallowsSameSiteNone :

Peringatan

Kode berikut hanya untuk demonstrasi:

  • Seharusnya tidak dianggap lengkap.
  • Ini tidak dipertahankan atau didukung.
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;
}

Menguji aplikasi untuk masalah SameSite

Aplikasi yang berinteraksi dengan situs jarak jauh seperti melalui login pihak ketiga perlu:

  • Uji interaksi di beberapa browser.
  • Terapkan deteksi dan mitigasi browser CookiePolicy yang dibahas dalam dokumen ini.

Uji aplikasi web menggunakan versi klien yang dapat ikut serta dalam perilaku SameSite baru. Chrome, Firefox, dan Chromium Edge semuanya memiliki bendera fitur keikutsertaan baru yang dapat digunakan untuk pengujian. Setelah aplikasi Anda menerapkan patch SameSite, uji dengan versi klien yang lebih lama, terutama Safari. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.

Uji dengan Chrome

Chrome 78+ memberikan hasil yang menyesatkan karena memiliki mitigasi sementara. Mitigasi sementara Chrome 78+ memungkinkan cookie berumur kurang dari dua menit. Chrome 76 atau 77 dengan bendera pengujian yang sesuai diaktifkan memberikan hasil yang lebih akurat. Untuk menguji tombol perilaku chrome://flags/#same-site-by-default-cookies SameSite baru ke Diaktifkan. Chrome versi lama (75 ke bawah) dilaporkan gagal dengan pengaturan baru None . Lihat Mendukung browser lama dalam dokumen ini.

Google tidak membuat versi chrome yang lebih lama tersedia. Ikuti petunjuk di Unduh Chromium untuk menguji versi Chrome yang lebih lama. Jangan unduh Chrome dari tautan yang disediakan dengan mencari chrome versi lama.

Mulai dari versi 80.0.3975.0Canary , mitigasi sementara Lax+POST dapat dinonaktifkan untuk tujuan pengujian menggunakan bendera --enable-features=SameSiteDefaultChecksMethodRigorously baru untuk memungkinkan pengujian situs dan layanan dalam status akhir akhir fitur tempat mitigasi telah dihapus. Untuk informasi selengkapnya, lihat Pembaruan SameSite Proyek Chromium

Uji dengan Safari

Safari 12 secara ketat menerapkan draf sebelumnya dan gagal ketika nilai baru None berada dalam cookie. None dihindari melalui kode deteksi browser Mendukung browser lama dalam dokumen ini. Uji login gaya OS berbasis Safari 12, Safari 13, dan WebKit menggunakan MSAL, ADAL, atau pustaka apa pun yang Anda gunakan. Masalahnya tergantung pada versi OS yang mendasar. OSX Mojave (10.14) dan iOS 12 diketahui memiliki masalah kompatibilitas dengan perilaku SameSite baru. Meningkatkan OS ke OSX Catalina (10.15) atau iOS 13 memperbaiki masalah. Safari saat ini tidak memiliki bendera keikutsertaan untuk menguji perilaku spesifikasi baru.

Uji dengan Firefox

Dukungan Firefox untuk standar baru dapat diuji pada versi 68+ dengan memilih ikut serta di about:config halaman dengan bendera network.cookie.sameSite.laxByDefaultfitur . Belum ada laporan masalah kompatibilitas dengan versi Firefox yang lebih lama.

Uji dengan browser Edge

Edge mendukung standar SameSite lama. Edge versi 44 tidak memiliki masalah kompatibilitas yang diketahui dengan standar baru.

Uji dengan Edge (Chromium)

Bendera SameSite diatur pada edge://flags/#same-site-by-default-cookies halaman. Tidak ada masalah kompatibilitas yang ditemukan dengan Edge Chromium.

Uji dengan Electron

Electron Versi termasuk versi Chromium yang lebih lama. Misalnya, versi yang Electron digunakan oleh Teams adalah Chromium 66, yang menunjukkan perilaku yang lebih lama. Anda harus melakukan pengujian kompatibilitas Anda sendiri dengan versi penggunaan Electron produk Anda. Lihat Mendukung browser lama di bagian berikut.

Sumber Daya Tambahan:

Sampel Dokumen
.NET Core MVC sampel ASP.NET Core 2.1 MVC SameSite cookie
Halaman .NET Core Razor ASP.NET sampel SameSite cookie Halaman Core 2.1 Razor