Cookie SameSite dan Open Web Interface untuk .NET (OWIN)
Oleh Rick Anderson
SameSite
adalah draf IETF yang dirancang untuk memberikan beberapa perlindungan terhadap serangan pemalsuan permintaan lintas situs (CSRF). Draf SameSite 2019:
- Memperlakukan cookie sebagai
SameSite=Lax
secara default. - Menyatakan cookie yang secara eksplisit menegaskan
SameSite=None
untuk mengaktifkan pengiriman lintas situs harus ditandai sebagaiSecure
.
Lax
bekerja untuk sebagian besar cookie aplikasi. Beberapa bentuk autentikasi seperti OpenID Connect (OIDC) dan WS-Federation default ke pengalihan berbasis POST. Pengalihan berbasis POST memicu SameSite
perlindungan browser, sehingga SameSite
dinonaktifkan untuk komponen-komponen ini. Sebagian besar login OAuth tidak terpengaruh karena perbedaan bagaimana permintaan mengalir. Semua komponen lain tidak diatur SameSite
secara default dan menggunakan perilaku default klien (lama atau baru).
Parameter None
menyebabkan masalah kompatibilitas dengan klien yang menerapkan standar draf 2016 sebelumnya (misalnya, iOS 12). Lihat Mendukung browser lama dalam dokumen ini.
Setiap komponen OWIN yang memancarkan cookie perlu memutuskan apakah SameSite
sesuai.
Untuk versi ASP.NET 4.x artikel ini, lihat Bekerja dengan cookie SameSite di ASP.NET.
Microsoft.Owin
memiliki implementasinya sendiri SameSite
:
- Itu tidak secara langsung tergantung pada yang ada di
System.Web
. SameSite
bekerja pada semua versi yang dapat ditargetkanMicrosoft.Owin
oleh paket, .NET 4.5 dan yang lebih baru.- Hanya komponen SystemWebCookieManager yang berinteraksi langsung dengan
System.Web
HttpCookie
kelas .
SystemWebCookieManager
tergantung pada API .NET 4.7.2 System.Web
untuk mengaktifkan SameSite
dukungan, dan patch untuk mengubah perilaku.
Alasan penggunaan SystemWebCookieManager
diuraikan dalam masalah integrasi cookie respons OWIN dan System.Web. SystemWebCookieManager
disarankan saat berjalan pada System.Web
.
Kode berikut diatur SameSite
ke Lax
:
owinContext.Response.Cookies.Append("My Key", "My Value", new CookieOptions()
{
SameSite = SameSiteMode.Lax
});
API berikut menggunakan SameSite
:
- Microsoft.Owin.SameSiteMode
- CookieOptions.SameSite
- Kelas CookieAuthenticationOptions
- CookieAuthenticationOptions.CookieSameSite
- ICookieManager
- SystemWebCookieManager
- SystemWebChunkingCookieManager
- CookieAuthenticationOptions.CookieManager
- OpenIdConnectAuthenticationOptions.CookieManager
Microsoft.Owin tidak pernah mendukung SameSite
standar draf 2016.
Dukungan untuk draf SameSite 2019 hanya tersedia di Microsoft.Owin
4.1.0 dan yang lebih baru. Tidak ada patch untuk versi sebelumnya.
Draf SameSite
spesifikasi tahun 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 sebagaiSecure
.None
adalah entri baru untuk memilih keluar. - Dijadwalkan untuk diaktifkan oleh Chrome secara default pada Feb 2020. Browser mulai beralih ke standar ini pada tahun 2019.
- Didukung oleh patch yang dikeluarkan seperti yang dijelaskan dalam artikel KB. Untuk informasi selengkapnya, lihat artikel KB yang mendukung SameSite di .NET Framework.
Standar 2016 SameSite
mengamanatkan bahwa nilai yang tidak diketahui harus diperlakukan sebagai SameSite=Strict
nilai. Aplikasi yang diakses dari browser lama yang mendukung standar 2016 SameSite
dapat rusak ketika mereka mendapatkan SameSite
properti dengan nilai None
. Aplikasi web harus menerapkan deteksi browser jika ingin mendukung browser yang lebih lama. ASP.NET tidak menerapkan deteksi browser karena nilai Agen Pengguna sangat volatil dan sering berubah. Titik ekstensi di ICookieManager memungkinkan penyambungan logika spesifik User-Agent.
Di Startup.Configuration
, tambahkan kode yang mirip dengan yang berikut ini:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
// … Your preexisting options …
CookieManager = new SameSiteCookieManager(
new SystemWebCookieManager())
});
// Remaining code removed for brevity.
Kode sebelumnya memerlukan patch .NET 4.7.2 atau yang lebih baru SameSite
.
Kode berikut menunjukkan contoh implementasi :SameSiteCookieManager
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 == Microsoft.Owin.SameSiteMode.None
&& DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
Dalam sampel sebelumnya, DisallowsSameSiteNone
dipanggil dalam CheckSameSite
metode . DisallowsSameSiteNone
adalah metode pengguna yang mendeteksi apakah agen pengguna tidak mendukung SameSite
None
:
private void CheckSameSite(IOwinContext context, CookieOptions options)
{
if (options.SameSite == Microsoft.Owin.SameSiteMode.None
&& DisallowsSameSiteNone(context))
{
options.SameSite = null;
}
}
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(IOwinContext context)
{
var userAgent = context.Request.Headers["User-Agent"];
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;
}
Aplikasi yang berinteraksi dengan situs jarak jauh seperti melalui login pihak ketiga perlu:
- Uji interaksi di beberapa browser.
- Terapkan deteksi dan mitigasi browser yang dibahas dalam dokumen ini.
Uji aplikasi web menggunakan versi klien yang dapat ikut serta dalam perilaku baru SameSite
. Chrome, Firefox, dan Chromium Edge semuanya memiliki bendera fitur keikutsertaan baru yang dapat digunakan untuk pengujian. Setelah aplikasi Anda menerapkan SameSite
patch, uji dengan versi klien yang lebih lama, terutama Safari. Untuk informasi selengkapnya, lihat Mendukung browser lama dalam dokumen ini.
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
baru SameSite
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.
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 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 baru SameSite
. Meningkatkan OS ke OSX Catalina (10.15) atau iOS 13 memperbaiki masalah. Safari saat ini tidak memiliki bendera keikutsertaan untuk menguji perilaku spesifikasi baru.
Dukungan Firefox untuk standar baru dapat diuji pada versi 68+ dengan memilih ikut serta di about:config
halaman dengan bendera network.cookie.sameSite.laxByDefault
fitur . Belum ada laporan masalah kompatibilitas dengan versi Firefox yang lebih lama.
Edge mendukung standar lama SameSite
. Edge versi 44 tidak memiliki masalah kompatibilitas yang diketahui dengan standar baru.
SameSite
bendera diatur pada edge://flags/#same-site-by-default-cookies
halaman. Tidak ada masalah kompatibilitas yang ditemukan dengan Edge Chromium.
Versi Electron mencakup versi Chromium yang lebih lama. Misalnya, versi Electron yang digunakan oleh Teams adalah Chromium 66, yang menunjukkan perilaku yang lebih lama. Anda harus melakukan pengujian kompatibilitas Anda sendiri dengan versi Electron yang digunakan produk Anda. Lihat Mendukung browser lama di bagian berikut.