Mencegah serangan Pemalsuan Permintaan Lintas Situs (XSRF/CSRF) di ASP.NET Core
Oleh Fiyaz Hasan dan Rick Anderson
Pemalsuan permintaan lintas situs adalah serangan terhadap aplikasi yang dihosting web di mana aplikasi web berbahaya dapat memengaruhi interaksi antara browser klien dan aplikasi web yang mempercayai browser tersebut. Serangan ini dimungkinkan karena browser web mengirim beberapa jenis token autentikasi secara otomatis dengan setiap permintaan ke situs web. Bentuk eksploitasi ini juga dikenal sebagai serangan satu klik atau naik sesi karena serangan memanfaatkan sesi yang diautentikasi pengguna sebelumnya. Pemalsuan permintaan lintas situs juga dikenal sebagai XSRF atau CSRF.
Contoh serangan CSRF:
Pengguna masuk
www.good-banking-site.example.com
menggunakan autentikasi formulir. Server mengautentikasi pengguna dan mengeluarkan respons yang menyertakan autentikasi cookie. Situs ini rentan terhadap serangan karena mempercayai permintaan apa pun yang diterimanya dengan autentikasi cookieyang valid.Pengguna mengunjungi situs berbahaya,
www.bad-crook-site.example.com
.Situs berbahaya,
www.bad-crook-site.example.com
, berisi formulir HTML yang mirip dengan contoh berikut:<h1>Congratulations! You're a Winner!</h1> <form action="https://good-banking-site.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Perhatikan bahwa posting formulir
action
ke situs yang rentan, bukan ke situs berbahaya. Ini adalah bagian "lintas situs" dari CSRF.Pengguna memilih tombol kirim. Browser membuat permintaan dan secara otomatis menyertakan autentikasi cookie untuk domain yang diminta,
www.good-banking-site.example.com
.Permintaan berjalan di
www.good-banking-site.example.com
server dengan konteks autentikasi pengguna dan dapat melakukan tindakan apa pun yang diizinkan untuk dilakukan oleh pengguna terautentikasi.
Selain skenario di mana pengguna memilih tombol untuk mengirimkan formulir, situs berbahaya dapat:
- Jalankan skrip yang secara otomatis mengirimkan formulir.
- Kirim pengiriman formulir sebagai permintaan AJAX.
- Sembunyikan formulir menggunakan CSS.
Skenario alternatif ini tidak memerlukan tindakan atau input apa pun dari pengguna selain awalnya mengunjungi situs berbahaya.
Menggunakan HTTPS tidak mencegah serangan CSRF. Situs berbahaya dapat mengirim https://www.good-banking-site.com/
permintaan semudah dapat mengirim permintaan yang tidak aman.
Beberapa serangan menargetkan titik akhir yang merespons permintaan GET, dalam hal ini tag gambar dapat digunakan untuk melakukan tindakan. Bentuk serangan ini umum terjadi di situs forum yang mengizinkan gambar tetapi memblokir JavaScript. Aplikasi yang mengubah status pada permintaan GET, di mana variabel atau sumber daya diubah, rentan terhadap serangan berbahaya. Permintaan GET yang mengubah status tidak aman. Praktik terbaik adalah tidak pernah mengubah status pada permintaan GET.
Serangan CSRF dimungkinkan terhadap aplikasi web yang menggunakan cookie untuk autentikasi karena:
- Browser menyimpan cookie yang dikeluarkan oleh aplikasi web.
- Cookie tersimpan mencakup cookie sesi untuk pengguna yang diautentikasi.
- Browser mengirim semua cookie yang terkait dengan domain ke aplikasi web setiap permintaan terlepas dari bagaimana permintaan ke aplikasi dihasilkan dalam browser.
Namun, serangan CSRF tidak terbatas pada mengeksploitasi cookie. Misalnya, autentikasi Dasar dan Hash juga rentan. Setelah pengguna masuk dengan autentikasi Dasar atau Hash, browser secara otomatis mengirim kredensial hingga sesi berakhir.
Dalam konteks ini, sesi mengacu pada sesi sisi klien tempat pengguna diautentikasi. Ini tidak terkait dengan sesi sisi server atau ASP.NET Middleware Sesi Inti.
Pengguna dapat melindungi dari kerentanan CSRF dengan mengambil tindakan pencegahan:
- Keluar dari aplikasi web setelah selesai menggunakannya.
- Hapus cookie browser secara berkala.
Namun, kerentanan CSRF pada dasarnya merupakan masalah dengan aplikasi web, bukan pengguna akhir.
Dasar-dasar autentikasi
CookieAutentikasi berbasis -adalah bentuk autentikasi yang populer. Sistem autentikasi berbasis token semakin populer, terutama untuk Aplikasi Halaman Tunggal (SPAs).
Cookieautentikasi berbasis
Saat pengguna mengautentikasi menggunakan nama pengguna dan kata sandi mereka, mereka mengeluarkan token yang berisi tiket autentikasi. Token dapat digunakan untuk autentikasi dan otorisasi. Token disimpan sebagai cookie yang dikirim dengan setiap permintaan yang dilakukan klien. Menghasilkan dan memvalidasi ini cookie dilakukan dengan Cookie Middleware Autentikasi. Middleware menserialisasikan prinsipal pengguna ke dalam terenkripsi cookie. Pada permintaan berikutnya, middleware memvalidasi cookie, membuat ulang prinsipal, dan menetapkan utama ke HttpContext.User properti .
Autentikasi berbasis token
Saat pengguna diautentikasi, mereka mengeluarkan token (bukan token antiforgery). Token berisi informasi pengguna dalam bentuk klaim atau token referensi yang menunjuk aplikasi ke status pengguna yang dipertahankan di aplikasi. Saat pengguna mencoba mengakses sumber daya yang memerlukan autentikasi, token dikirim ke aplikasi dengan header otorisasi tambahan dalam bentuk token Pembawa. Pendekatan ini membuat aplikasi tanpa status. Dalam setiap permintaan berikutnya, token diteruskan dalam permintaan validasi sisi server. Token ini tidak dienkripsi; dikodekan. Di server, token didekodekan untuk mengakses informasinya. Untuk mengirim token pada permintaan berikutnya, simpan token di penyimpanan lokal browser. Menempatkan token di penyimpanan lokal browser dan mengambilnya dan menggunakannya sebagai token pembawa memberikan perlindungan terhadap serangan CSRF. Namun, jika aplikasi rentan terhadap injeksi skrip melalui XSS atau file JavaScript eksternal yang disusupi, penyerang cyber dapat mengambil nilai apa pun dari penyimpanan lokal dan mengirimkannya ke diri mereka sendiri. ASP.NET Core mengodekan semua output sisi server dari variabel secara default, mengurangi risiko XSS. Jika Anda mengambil alih perilaku ini dengan menggunakan Html.Raw atau kode kustom dengan input yang tidak tepercaya, Maka Anda dapat meningkatkan risiko XSS.
Jangan khawatir tentang kerentanan CSRF jika token disimpan di penyimpanan lokal browser. CSRF menjadi perhatian ketika token disimpan dalam cookie. Untuk informasi selengkapnya, lihat sampel kode SPA masalah GitHub menambahkan dua cookie.
Beberapa aplikasi yang dihosting di satu domain
Lingkungan hosting bersama rentan terhadap pembajakan sesi, CSRF masuk, dan serangan lainnya.
Meskipun example1.contoso.net
dan example2.contoso.net
merupakan host yang berbeda, ada hubungan kepercayaan implisit antara host di *.contoso.net
bawah domain. Hubungan kepercayaan implisit ini memungkinkan host yang berpotensi tidak tepercaya untuk memengaruhi cookie satu sama lain (kebijakan asal yang sama yang mengatur permintaan AJAX tidak selalu berlaku untuk cookie HTTP).
Serangan yang mengeksploitasi cookie tepercaya antara aplikasi yang dihosting di domain yang sama dapat dicegah dengan tidak berbagi domain. Saat setiap aplikasi dihosting di domainnya sendiri, tidak ada hubungan kepercayaan implisit cookie untuk dieksploitasi.
Antiforgery dalam ASP.NET Core
Peringatan
ASP.NET Core mengimplementasikan antiforgery menggunakan ASP.NET Core Data Protection. Tumpukan perlindungan data harus dikonfigurasi untuk bekerja di farm server. Untuk informasi selengkapnya, lihat Mengonfigurasi perlindungan data.
Middleware antiforgery ditambahkan ke kontainer injeksi Dependensi ketika salah satu API berikut dipanggil dalam Program.cs
:
Untuk informasi selengkapnya, lihat Antiforgery dengan API Minimal.
FormTagHelper menyuntikkan token anti-pemalsuan ke dalam elemen formulir HTML. Markup berikut dalam Razor file secara otomatis menghasilkan token antiforgery:
<form method="post">
<!-- ... -->
</form>
Demikian pula, IHtmlHelper.BeginForm menghasilkan token antiforgery secara default jika metode formulir bukan GET.
Pembuatan otomatis token antiforgery untuk elemen formulir HTML terjadi ketika <form>
tag berisi method="post"
atribut dan salah satu dari yang berikut ini benar:
- Atribut tindakan kosong (
action=""
). - Atribut tindakan tidak disediakan (
<form method="post">
).
Pembuatan token antiforgeri otomatis untuk elemen formulir HTML dapat dinonaktifkan:
Nonaktifkan token antiforgery secara eksplisit dengan
asp-antiforgery
atribut :<form method="post" asp-antiforgery="false"> <!-- ... --> </form>
Elemen formulir ditolak dari Pembantu Tag dengan menggunakan simbol penolakan Pembantu Tag ! :
<!form method="post"> <!-- ... --> </!form>
FormTagHelper
Hapus dari tampilan.FormTagHelper
dapat dihapus dari tampilan dengan menambahkan direktif berikut ke Razor tampilan:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Catatan
Razor Halaman secara otomatis dilindungi dari XSRF/CSRF. Untuk informasi selengkapnya, lihat XSRF/CSRF dan Razor Pages.
Pendekatan paling umum untuk melindungi dari serangan CSRF adalah menggunakan Pola Token Penyinkron (STP). STP digunakan saat pengguna meminta halaman dengan data formulir:
- Server mengirim token yang terkait dengan pengguna identity saat ini ke klien.
- Klien mengirim kembali token ke server untuk verifikasi.
- Jika server menerima token yang tidak cocok dengan pengguna identityyang diautentikasi, permintaan ditolak.
Token unik dan tidak dapat diprediksi. Token juga dapat digunakan untuk memastikan urutan yang tepat dari serangkaian permintaan (misalnya, memastikan urutan permintaan: halaman 1 > halaman 2 > halaman 3). Semua formulir dalam templat ASP.NET Core MVC dan Razor Pages menghasilkan token antiforgery. Sepasang contoh tampilan berikut menghasilkan token antiforgery:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Secara eksplisit menambahkan token antiforgery ke <form>
elemen tanpa menggunakan Pembantu Tag dengan pembantu @Html.AntiForgeryToken
HTML :
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Dalam setiap kasus sebelumnya, ASP.NET Core menambahkan bidang formulir tersembunyi yang mirip dengan contoh berikut:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core mencakup tiga filter untuk bekerja dengan token antiforgery:
Antiforgery dengan AddControllers
AddControllers Panggilan tidak mengaktifkan token antiforgery. AddControllersWithViews harus dipanggil untuk memiliki dukungan token antiforgery bawaan.
Beberapa tab browser dan Pola Token Penyinkron
Dengan Pola Token Penyinkron, hanya halaman yang terakhir dimuat yang berisi token antiforgery yang valid. Menggunakan beberapa tab bisa bermasalah. Misalnya, jika pengguna membuka beberapa tab:
- Hanya tab yang terakhir dimuat yang berisi token antiforgery yang valid.
- Permintaan yang dibuat dari tab yang dimuat sebelumnya gagal dengan kesalahan:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Pertimbangkan pola perlindungan CSRF alternatif jika ini menimbulkan masalah.
Mengonfigurasi antiforgery dengan AntiforgeryOptions
Sesuaikan AntiforgeryOptions dalam Program.cs
:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Atur properti antiforgery Cookie
menggunakan properti kelas , seperti yang CookieBuilder ditunjukkan dalam tabel berikut.
Opsi | Deskripsi |
---|---|
Cookie | Menentukan pengaturan yang digunakan untuk membuat cookie antiforgery. |
FormFieldName | Nama bidang formulir tersembunyi yang digunakan oleh sistem antiforgery untuk merender token antiforgery dalam tampilan. |
HeaderName | Nama header yang digunakan oleh sistem antiforgery. Jika null , sistem hanya mempertimbangkan data formulir. |
SuppressXFrameOptionsHeader | Menentukan apakah akan menekan pembuatan X-Frame-Options header. Secara default, header dihasilkan dengan nilai "SAMEORIGIN". Default ke false . |
Untuk informasi selengkapnya, lihat CookieAuthenticationOptions .
Hasilkan token antiforgery dengan IAntiforgery
IAntiforgery menyediakan API untuk mengonfigurasi fitur antiforgery. IAntiforgery
dapat diminta dalam Program.cs
menggunakan WebApplication.Services. Contoh berikut menggunakan middleware dari halaman aplikasi home untuk menghasilkan token antiforgery dan mengirimkannya dalam respons sebagai cookie:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
Contoh sebelumnya menetapkan bernama cookie XSRF-TOKEN
. Klien dapat membaca ini cookie dan memberikan nilainya sebagai header yang dilampirkan ke permintaan AJAX. Misalnya, Angular menyertakan perlindungan XSRF bawaan yang membaca nama cookie secara XSRF-TOKEN
default.
Memerlukan validasi antiforgery
Filter tindakan ValidateAntiForgeryToken dapat diterapkan ke tindakan individual, pengontrol, atau secara global. Permintaan yang dibuat untuk tindakan yang menerapkan filter ini diblokir kecuali permintaan menyertakan token antiforgery yang valid:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
Atribut ValidateAntiForgeryToken
memerlukan token untuk permintaan ke metode tindakan yang ditandainya, termasuk permintaan HTTP GET. ValidateAntiForgeryToken
Jika atribut diterapkan di seluruh pengontrol aplikasi, atribut dapat ditimpa dengan IgnoreAntiforgeryToken
atribut .
Memvalidasi token antiforgery secara otomatis hanya untuk metode HTTP yang tidak aman
Alih-alih menerapkan ValidateAntiForgeryToken
atribut secara luas dan kemudian menimpanya dengan IgnoreAntiforgeryToken
atribut, atribut AutoValidateAntiforgeryToken dapat digunakan. Atribut ini berfungsi secara identik dengan ValidateAntiForgeryToken
atribut , kecuali bahwa atribut ini tidak memerlukan token untuk permintaan yang dibuat menggunakan metode HTTP berikut:
- GET
- HEAD
- OPSI
- TRACE
Sebaiknya gunakan AutoValidateAntiforgeryToken
secara luas untuk skenario non-API. Atribut ini memastikan tindakan POST dilindungi secara default. Alternatifnya adalah mengabaikan token antiforgery secara default, kecuali ValidateAntiForgeryToken
diterapkan ke metode tindakan individual. Lebih mungkin dalam skenario ini untuk metode tindakan POST dibiarkan tidak terlindungi secara tidak sengaja, membuat aplikasi rentan terhadap serangan CSRF. Semua POS harus mengirim token antiforgery.
API tidak memiliki mekanisme otomatis untuk mengirim non-bagiancookie token. Implementasi mungkin tergantung pada implementasi kode klien. Beberapa contoh ditunjukkan di bawah ini:
Contoh tingkat kelas:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Contoh global:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Mengambil alih atribut antiforgery global atau pengontrol
Filter IgnoreAntiforgeryToken digunakan untuk menghilangkan kebutuhan token antiforgery untuk tindakan tertentu (atau pengontrol). Saat diterapkan, filter ini mengambil alih ValidateAntiForgeryToken
dan AutoValidateAntiforgeryToken
filter yang ditentukan pada tingkat yang lebih tinggi (secara global atau pada pengontrol).
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Refresh token setelah autentikasi
Token harus di-refresh setelah pengguna diautentikasi dengan mengalihkan pengguna ke halaman tampilan atau Razor Halaman.
JavaScript, AJAX, dan SPAs
Dalam aplikasi tradisional berbasis HTML, token antiforgery diteruskan ke server menggunakan bidang formulir tersembunyi. Di aplikasi dan SPAs berbasis JavaScript modern, banyak permintaan dibuat secara terprogram. Permintaan AJAX ini dapat menggunakan teknik lain, seperti header permintaan atau cookie, untuk mengirim token.
Jika cookie digunakan untuk menyimpan token autentikasi dan untuk mengautentikasi permintaan API di server, CSRF adalah masalah potensial. Jika penyimpanan lokal digunakan untuk menyimpan token, kerentanan CSRF mungkin dimitigasi karena nilai dari penyimpanan lokal tidak dikirim secara otomatis ke server dengan setiap permintaan. Menggunakan penyimpanan lokal untuk menyimpan token antiforgery pada klien dan mengirim token sebagai header permintaan adalah pendekatan yang direkomendasikan.
Blazor
Untuk informasi selengkapnya, lihat autentikasi dan otorisasi ASP.NET CoreBlazor.
JavaScript
Menggunakan JavaScript dengan tampilan, token dapat dibuat menggunakan layanan dari dalam tampilan. IAntiforgery Masukkan layanan ke dalam tampilan dan panggil GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
Contoh sebelumnya menggunakan JavaScript untuk membaca nilai bidang tersembunyi untuk header AJAX POST.
Pendekatan ini menghilangkan kebutuhan untuk berurusan langsung dengan pengaturan cookie dari server atau membacanya dari klien. Namun, saat menyuntikkan layanan tidak dimungkinkan IAntiforgery , gunakan JavaScript untuk mengakses token dalam cookie:
- Akses token dalam permintaan tambahan ke server, biasanya .
same-origin
- cookieGunakan konten 's untuk membuat header dengan nilai token.
Dengan asumsi skrip mengirim token di header permintaan yang disebut X-XSRF-TOKEN
, konfigurasikan layanan antiforgery untuk X-XSRF-TOKEN
mencari header:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Contoh berikut menambahkan titik akhir terproteksi yang menulis token permintaan ke JavaScript yang dapat cookiedibaca :
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
Contoh berikut menggunakan JavaScript untuk membuat permintaan AJAX untuk mendapatkan token dan membuat permintaan lain dengan header yang sesuai:
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Catatan
Ketika token antiforgery disediakan di header permintaan dan dalam payload formulir, hanya token di header yang divalidasi.
Antiforgery dengan API Minimal
Hubungi AddAntiforgery dan UseAntiforgery(IApplicationBuilder) untuk mendaftarkan layanan antiforgery di DI. Token antiforgery digunakan untuk mengurangi serangan pemalsuan permintaan lintas situs.
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
app.MapGet("/", () => "Hello World!");
app.Run();
Middleware antiforgery:
- Tidak menyingkat sirkuit eksekusi rest alur permintaan.
- Mengatur IAntiforgeryValidationFeature di HttpContext.Features dari permintaan saat ini.
Token antiforgery hanya divalidasi jika:
- Titik akhir berisi metadata yang mengimplementasikan IAntiforgeryMetadata di mana
RequiresValidation=true
. - Metode HTTP yang terkait dengan titik akhir adalah metode HTTP yang relevan. Metode yang relevan adalah semua metode HTTP kecuali untuk TRACE, OPTIONS, HEAD, dan GET.
- Permintaan dikaitkan dengan titik akhir yang valid.
Catatan: Saat diaktifkan secara manual, middleware antiforgery harus berjalan setelah middleware autentikasi dan otorisasi untuk mencegah membaca data formulir saat pengguna tidak diautentikasi.
Secara default, API minimal yang menerima data formulir memerlukan validasi token antiforgery.
Pertimbangkan metode berikut GenerateForm
:
public static string GenerateForm(string action,
AntiforgeryTokenSet token, bool UseToken=true)
{
string tokenInput = "";
if (UseToken)
{
tokenInput = $@"<input name=""{token.FormFieldName}""
type=""hidden"" value=""{token.RequestToken}"" />";
}
return $@"
<html><body>
<form action=""{action}"" method=""POST"" enctype=""multipart/form-data"">
{tokenInput}
<input type=""text"" name=""name"" />
<input type=""date"" name=""dueDate"" />
<input type=""checkbox"" name=""isCompleted"" />
<input type=""submit"" />
</form>
</body></html>
";
}
Kode sebelumnya memiliki tiga argumen, tindakan, token antiforgery, dan yang bool
menunjukkan apakah token harus digunakan.
Pertimbangkan sampel berikut:
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
// Pass token
app.MapGet("/", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo", token), "text/html");
});
// Don't pass a token, fails
app.MapGet("/SkipToken", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo",token, false ), "text/html");
});
// Post to /todo2. DisableAntiforgery on that endpoint so no token needed.
app.MapGet("/DisableAntiforgery", (HttpContext context, IAntiforgery antiforgery) =>
{
var token = antiforgery.GetAndStoreTokens(context);
return Results.Content(MyHtml.GenerateForm("/todo2", token, false), "text/html");
});
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
app.Run();
class Todo
{
public required string Name { get; set; }
public bool IsCompleted { get; set; }
public DateTime DueDate { get; set; }
}
public static class MyHtml
{
public static string GenerateForm(string action,
AntiforgeryTokenSet token, bool UseToken=true)
{
string tokenInput = "";
if (UseToken)
{
tokenInput = $@"<input name=""{token.FormFieldName}""
type=""hidden"" value=""{token.RequestToken}"" />";
}
return $@"
<html><body>
<form action=""{action}"" method=""POST"" enctype=""multipart/form-data"">
{tokenInput}
<input type=""text"" name=""name"" />
<input type=""date"" name=""dueDate"" />
<input type=""checkbox"" name=""isCompleted"" />
<input type=""submit"" />
</form>
</body></html>
";
}
}
Dalam kode sebelumnya, posting ke:
/todo
memerlukan token antiforgery yang valid./todo2
tidak memerlukan token antiforgery yang valid karenaDisableAntiforgery
dipanggil.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
POST untuk:
/todo
dari formulir yang dihasilkan oleh/
titik akhir berhasil karena token antiforgery valid./todo
dari formulir yang dihasilkan oleh/SkipToken
kegagalan karena antiforgery tidak disertakan./todo2
dari formulir yang dihasilkan oleh/DisableAntiforgery
titik akhir berhasil karena antiforgery tidak diperlukan.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
Ketika formulir dikirimkan tanpa token antiforgery yang valid:
- Di lingkungan pengembangan, pengecualian dilemparkan.
- Di lingkungan produksi, pesan dicatat.
Autentikasi Windows dan cookie antiforgery
Saat menggunakan Autentikasi Windows, titik akhir aplikasi harus dilindungi dari serangan CSRF dengan cara yang sama seperti yang dilakukan untuk cookie. Browser secara implisit mengirim konteks autentikasi ke server dan titik akhir perlu dilindungi dari serangan CSRF.
Perluas antiforgery
Jenis ini IAntiforgeryAdditionalDataProvider memungkinkan pengembang untuk memperluas perilaku sistem anti-CSRF dengan melakukan round-tripping data tambahan di setiap token. Metode GetAdditionalData ini dipanggil setiap kali token bidang dihasilkan, dan nilai pengembalian disematkan dalam token yang dihasilkan. Pelaksana dapat mengembalikan tanda waktu, nonce, atau nilai lain lalu memanggil ValidateAdditionalData untuk memvalidasi data ini saat token divalidasi. Nama pengguna klien sudah disematkan dalam token yang dihasilkan, sehingga tidak perlu menyertakan informasi ini. Jika token menyertakan data tambahan tetapi tidak IAntiForgeryAdditionalDataProvider
dikonfigurasi, data tambahan tidak divalidasi.
Sumber Daya Tambahan:
Pemalsuan permintaan lintas situs (juga dikenal sebagai XSRF atau CSRF) adalah serangan terhadap aplikasi yang dihosting web di mana aplikasi web berbahaya dapat memengaruhi interaksi antara browser klien dan aplikasi web yang mempercayai browser tersebut. Serangan ini dimungkinkan karena browser web mengirim beberapa jenis token autentikasi secara otomatis dengan setiap permintaan ke situs web. Bentuk eksploitasi ini juga dikenal sebagai serangan satu klik atau naik sesi karena serangan memanfaatkan sesi yang diautentikasi pengguna sebelumnya.
Contoh serangan CSRF:
Pengguna masuk
www.good-banking-site.example.com
menggunakan autentikasi formulir. Server mengautentikasi pengguna dan mengeluarkan respons yang menyertakan autentikasi cookie. Situs ini rentan terhadap serangan karena mempercayai permintaan apa pun yang diterimanya dengan autentikasi cookieyang valid.Pengguna mengunjungi situs berbahaya,
www.bad-crook-site.example.com
.Situs berbahaya,
www.bad-crook-site.example.com
, berisi formulir HTML yang mirip dengan contoh berikut:<h1>Congratulations! You're a Winner!</h1> <form action="https://good-banking-site.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Perhatikan bahwa posting formulir
action
ke situs yang rentan, bukan ke situs berbahaya. Ini adalah bagian "lintas situs" dari CSRF.Pengguna memilih tombol kirim. Browser membuat permintaan dan secara otomatis menyertakan autentikasi cookie untuk domain yang diminta,
www.good-banking-site.example.com
.Permintaan berjalan di
www.good-banking-site.example.com
server dengan konteks autentikasi pengguna dan dapat melakukan tindakan apa pun yang diizinkan untuk dilakukan oleh pengguna terautentikasi.
Selain skenario di mana pengguna memilih tombol untuk mengirimkan formulir, situs berbahaya dapat:
- Jalankan skrip yang secara otomatis mengirimkan formulir.
- Kirim pengiriman formulir sebagai permintaan AJAX.
- Sembunyikan formulir menggunakan CSS.
Skenario alternatif ini tidak memerlukan tindakan atau input apa pun dari pengguna selain awalnya mengunjungi situs berbahaya.
Menggunakan HTTPS tidak mencegah serangan CSRF. Situs berbahaya dapat mengirim https://www.good-banking-site.com/
permintaan semudah dapat mengirim permintaan yang tidak aman.
Beberapa serangan menargetkan titik akhir yang merespons permintaan GET, dalam hal ini tag gambar dapat digunakan untuk melakukan tindakan. Bentuk serangan ini umum terjadi di situs forum yang mengizinkan gambar tetapi memblokir JavaScript. Aplikasi yang mengubah status pada permintaan GET, di mana variabel atau sumber daya diubah, rentan terhadap serangan berbahaya. Permintaan GET yang mengubah status tidak aman. Praktik terbaik adalah tidak pernah mengubah status pada permintaan GET.
Serangan CSRF dimungkinkan terhadap aplikasi web yang menggunakan cookie untuk autentikasi karena:
- Browser menyimpan cookie yang dikeluarkan oleh aplikasi web.
- Cookie tersimpan mencakup cookie sesi untuk pengguna yang diautentikasi.
- Browser mengirim semua cookie yang terkait dengan domain ke aplikasi web setiap permintaan terlepas dari bagaimana permintaan ke aplikasi dihasilkan dalam browser.
Namun, serangan CSRF tidak terbatas pada mengeksploitasi cookie. Misalnya, autentikasi Dasar dan Hash juga rentan. Setelah pengguna masuk dengan autentikasi Dasar atau Hash, browser secara otomatis mengirim kredensial hingga sesi berakhir.
Dalam konteks ini, sesi mengacu pada sesi sisi klien tempat pengguna diautentikasi. Ini tidak terkait dengan sesi sisi server atau ASP.NET Middleware Sesi Inti.
Pengguna dapat melindungi dari kerentanan CSRF dengan mengambil tindakan pencegahan:
- Keluar dari aplikasi web setelah selesai menggunakannya.
- Hapus cookie browser secara berkala.
Namun, kerentanan CSRF pada dasarnya merupakan masalah dengan aplikasi web, bukan pengguna akhir.
Dasar-dasar autentikasi
CookieAutentikasi berbasis -adalah bentuk autentikasi yang populer. Sistem autentikasi berbasis token semakin populer, terutama untuk Aplikasi Halaman Tunggal (SPAs).
Cookieautentikasi berbasis
Saat pengguna mengautentikasi menggunakan nama pengguna dan kata sandi mereka, mereka mengeluarkan token, yang berisi tiket autentikasi yang dapat digunakan untuk autentikasi dan otorisasi. Token disimpan sebagai cookie yang dikirim dengan setiap permintaan yang dilakukan klien. Menghasilkan dan memvalidasi ini cookie dilakukan oleh Cookie Middleware Autentikasi. Middleware menserialisasikan prinsipal pengguna ke dalam terenkripsi cookie. Pada permintaan berikutnya, middleware memvalidasi cookie, membuat ulang prinsipal, dan menetapkan utama ke HttpContext.User properti .
Autentikasi berbasis token
Saat pengguna diautentikasi, mereka mengeluarkan token (bukan token antiforgery). Token berisi informasi pengguna dalam bentuk klaim atau token referensi yang menunjuk aplikasi ke status pengguna yang dipertahankan di aplikasi. Saat pengguna mencoba mengakses sumber daya yang memerlukan autentikasi, token dikirim ke aplikasi dengan header otorisasi tambahan dalam bentuk token Pembawa. Pendekatan ini membuat aplikasi tanpa status. Dalam setiap permintaan berikutnya, token diteruskan dalam permintaan validasi sisi server. Token ini tidak dienkripsi; dikodekan. Di server, token didekodekan untuk mengakses informasinya. Untuk mengirim token pada permintaan berikutnya, simpan token di penyimpanan lokal browser. Menempatkan token di penyimpanan lokal browser dan mengambilnya dan menggunakannya sebagai token pembawa memberikan perlindungan terhadap serangan CSRF. Namun, jika aplikasi rentan terhadap injeksi skrip melalui XSS atau file javascript eksternal yang disusupi, penyerang cyber dapat mengambil nilai apa pun dari penyimpanan lokal dan mengirimkannya ke diri mereka sendiri. ASP.NET Core mengodekan semua output sisi server dari variabel secara default, mengurangi risiko XSS. Jika Anda mengambil alih perilaku ini dengan menggunakan Html.Raw atau kode kustom dengan input yang tidak tepercaya, Maka Anda dapat meningkatkan risiko XSS.
Jangan khawatir tentang kerentanan CSRF jika token disimpan di penyimpanan lokal browser. CSRF menjadi perhatian ketika token disimpan dalam cookie. Untuk informasi selengkapnya, lihat sampel kode SPA masalah GitHub menambahkan dua cookie.
Beberapa aplikasi yang dihosting di satu domain
Lingkungan hosting bersama rentan terhadap pembajakan sesi, CSRF masuk, dan serangan lainnya.
Meskipun example1.contoso.net
dan example2.contoso.net
merupakan host yang berbeda, ada hubungan kepercayaan implisit antara host di *.contoso.net
bawah domain. Hubungan kepercayaan implisit ini memungkinkan host yang berpotensi tidak tepercaya untuk memengaruhi cookie satu sama lain (kebijakan asal yang sama yang mengatur permintaan AJAX tidak selalu berlaku untuk cookie HTTP).
Serangan yang mengeksploitasi cookie tepercaya antara aplikasi yang dihosting di domain yang sama dapat dicegah dengan tidak berbagi domain. Saat setiap aplikasi dihosting di domainnya sendiri, tidak ada hubungan kepercayaan implisit cookie untuk dieksploitasi.
Antiforgery dalam ASP.NET Core
Peringatan
ASP.NET Core mengimplementasikan antiforgery menggunakan ASP.NET Core Data Protection. Tumpukan perlindungan data harus dikonfigurasi untuk bekerja di farm server. Untuk informasi selengkapnya, lihat Mengonfigurasi perlindungan data.
Middleware antiforgery ditambahkan ke kontainer injeksi Dependensi ketika salah satu API berikut dipanggil dalam Program.cs
:
FormTagHelper menyuntikkan token anti-pemalsuan ke dalam elemen formulir HTML. Markup berikut dalam Razor file secara otomatis menghasilkan token antiforgery:
<form method="post">
<!-- ... -->
</form>
Demikian pula, IHtmlHelper.BeginForm menghasilkan token antiforgery secara default jika metode formulir bukan GET.
Pembuatan otomatis token antiforgery untuk elemen formulir HTML terjadi ketika <form>
tag berisi method="post"
atribut dan salah satu dari yang berikut ini benar:
- Atribut tindakan kosong (
action=""
). - Atribut tindakan tidak disediakan (
<form method="post">
).
Pembuatan token antiforgeri otomatis untuk elemen formulir HTML dapat dinonaktifkan:
Nonaktifkan token antiforgery secara eksplisit dengan
asp-antiforgery
atribut :<form method="post" asp-antiforgery="false"> <!-- ... --> </form>
Elemen formulir ditolak dari Pembantu Tag dengan menggunakan simbol penolakan Pembantu Tag ! :
<!form method="post"> <!-- ... --> </!form>
FormTagHelper
Hapus dari tampilan.FormTagHelper
dapat dihapus dari tampilan dengan menambahkan direktif berikut ke Razor tampilan:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Catatan
Razor Halaman secara otomatis dilindungi dari XSRF/CSRF. Untuk informasi selengkapnya, lihat XSRF/CSRF dan Razor Pages.
Pendekatan paling umum untuk bertahan dari serangan CSRF adalah menggunakan Pola Token Penyinkron (STP). STP digunakan saat pengguna meminta halaman dengan data formulir:
- Server mengirim token yang terkait dengan pengguna identity saat ini ke klien.
- Klien mengirim kembali token ke server untuk verifikasi.
- Jika server menerima token yang tidak cocok dengan pengguna identityyang diautentikasi, permintaan ditolak.
Token unik dan tidak dapat diprediksi. Token juga dapat digunakan untuk memastikan urutan yang tepat dari serangkaian permintaan (misalnya, memastikan urutan permintaan: halaman 1 > halaman 2 > halaman 3). Semua formulir dalam templat ASP.NET Core MVC dan Razor Pages menghasilkan token antiforgery. Sepasang contoh tampilan berikut menghasilkan token antiforgery:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Secara eksplisit menambahkan token antiforgery ke <form>
elemen tanpa menggunakan Pembantu Tag dengan pembantu @Html.AntiForgeryToken
HTML :
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Dalam setiap kasus sebelumnya, ASP.NET Core menambahkan bidang formulir tersembunyi yang mirip dengan contoh berikut:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core mencakup tiga filter untuk bekerja dengan token antiforgery:
Antiforgery dengan AddControllers
AddControllers Panggilan tidak mengaktifkan token antiforgery. AddControllersWithViews harus dipanggil untuk memiliki dukungan token antiforgery bawaan.
Beberapa tab browser dan Pola Token Penyinkron
Dengan Pola Token Penyinkron, hanya halaman yang terakhir dimuat yang berisi token antiforgery yang valid. Menggunakan beberapa tab bisa bermasalah. Misalnya, jika pengguna membuka beberapa tab:
- Hanya tab yang terakhir dimuat yang berisi token antiforgery yang valid.
- Permintaan yang dibuat dari tab yang dimuat sebelumnya gagal dengan kesalahan:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Pertimbangkan pola perlindungan CSRF alternatif jika ini menimbulkan masalah.
Mengonfigurasi antiforgery dengan AntiforgeryOptions
Sesuaikan AntiforgeryOptions dalam Program.cs
:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Atur properti antiforgery Cookie
menggunakan properti kelas , seperti yang CookieBuilder ditunjukkan dalam tabel berikut.
Opsi | Deskripsi |
---|---|
Cookie | Menentukan pengaturan yang digunakan untuk membuat cookie antiforgery. |
FormFieldName | Nama bidang formulir tersembunyi yang digunakan oleh sistem antiforgery untuk merender token antiforgery dalam tampilan. |
HeaderName | Nama header yang digunakan oleh sistem antiforgery. Jika null , sistem hanya mempertimbangkan data formulir. |
SuppressXFrameOptionsHeader | Menentukan apakah akan menekan pembuatan X-Frame-Options header. Secara default, header dihasilkan dengan nilai "SAMEORIGIN". Default ke false . |
Untuk informasi selengkapnya, lihat CookieAuthenticationOptions .
Hasilkan token antiforgery dengan IAntiforgery
IAntiforgery menyediakan API untuk mengonfigurasi fitur antiforgery. IAntiforgery
dapat diminta dalam Program.cs
menggunakan WebApplication.Services. Contoh berikut menggunakan middleware dari halaman aplikasi home untuk menghasilkan token antiforgery dan mengirimkannya dalam respons sebagai cookie:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
Contoh sebelumnya menetapkan bernama cookie XSRF-TOKEN
. Klien dapat membaca ini cookie dan memberikan nilainya sebagai header yang dilampirkan ke permintaan AJAX. Misalnya, Angular menyertakan perlindungan XSRF bawaan yang membaca nama cookie secara XSRF-TOKEN
default.
Memerlukan validasi antiforgery
Filter tindakan ValidateAntiForgeryToken dapat diterapkan ke tindakan individual, pengontrol, atau secara global. Permintaan yang dibuat untuk tindakan yang menerapkan filter ini diblokir kecuali permintaan menyertakan token antiforgery yang valid:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
Atribut ValidateAntiForgeryToken
memerlukan token untuk permintaan ke metode tindakan yang ditandainya, termasuk permintaan HTTP GET. ValidateAntiForgeryToken
Jika atribut diterapkan di seluruh pengontrol aplikasi, atribut dapat ditimpa dengan IgnoreAntiforgeryToken
atribut .
Memvalidasi token antiforgery secara otomatis hanya untuk metode HTTP yang tidak aman
Alih-alih menerapkan ValidateAntiForgeryToken
atribut secara luas dan kemudian menimpanya dengan IgnoreAntiforgeryToken
atribut, atribut AutoValidateAntiforgeryToken dapat digunakan. Atribut ini berfungsi secara identik dengan ValidateAntiForgeryToken
atribut , kecuali bahwa atribut ini tidak memerlukan token untuk permintaan yang dibuat menggunakan metode HTTP berikut:
- GET
- HEAD
- OPSI
- TRACE
Sebaiknya gunakan AutoValidateAntiforgeryToken
secara luas untuk skenario non-API. Atribut ini memastikan tindakan POST dilindungi secara default. Alternatifnya adalah mengabaikan token antiforgery secara default, kecuali ValidateAntiForgeryToken
diterapkan ke metode tindakan individual. Lebih mungkin dalam skenario ini untuk metode tindakan POST dibiarkan tidak terlindungi secara tidak sengaja, membuat aplikasi rentan terhadap serangan CSRF. Semua POS harus mengirim token antiforgery.
API tidak memiliki mekanisme otomatis untuk mengirim non-bagiancookie token. Implementasi mungkin tergantung pada implementasi kode klien. Beberapa contoh ditunjukkan di bawah ini:
Contoh tingkat kelas:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Contoh global:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Mengambil alih atribut antiforgery global atau pengontrol
Filter IgnoreAntiforgeryToken digunakan untuk menghilangkan kebutuhan token antiforgery untuk tindakan tertentu (atau pengontrol). Saat diterapkan, filter ini mengambil alih ValidateAntiForgeryToken
dan AutoValidateAntiforgeryToken
filter yang ditentukan pada tingkat yang lebih tinggi (secara global atau pada pengontrol).
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Refresh token setelah autentikasi
Token harus di-refresh setelah pengguna diautentikasi dengan mengalihkan pengguna ke halaman tampilan atau Razor Halaman.
JavaScript, AJAX, dan SPAs
Dalam aplikasi tradisional berbasis HTML, token antiforgery diteruskan ke server menggunakan bidang formulir tersembunyi. Di aplikasi dan SPAs berbasis JavaScript modern, banyak permintaan dibuat secara terprogram. Permintaan AJAX ini dapat menggunakan teknik lain (seperti header permintaan atau cookie) untuk mengirim token.
Jika cookie digunakan untuk menyimpan token autentikasi dan untuk mengautentikasi permintaan API di server, CSRF adalah masalah potensial. Jika penyimpanan lokal digunakan untuk menyimpan token, kerentanan CSRF mungkin dimitigasi karena nilai dari penyimpanan lokal tidak dikirim secara otomatis ke server dengan setiap permintaan. Menggunakan penyimpanan lokal untuk menyimpan token antiforgery pada klien dan mengirim token sebagai header permintaan adalah pendekatan yang direkomendasikan.
JavaScript
Menggunakan JavaScript dengan tampilan, token dapat dibuat menggunakan layanan dari dalam tampilan. IAntiforgery Masukkan layanan ke dalam tampilan dan panggil GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
Contoh sebelumnya menggunakan JavaScript untuk membaca nilai bidang tersembunyi untuk header AJAX POST.
Pendekatan ini menghilangkan kebutuhan untuk berurusan langsung dengan pengaturan cookie dari server atau membacanya dari klien. Namun, saat menyuntikkan layanan tidak dimungkinkan IAntiforgery , gunakan JavaScript untuk mengakses token dalam cookie:
- Akses token dalam permintaan tambahan ke server, biasanya .
same-origin
- cookieGunakan konten 's untuk membuat header dengan nilai token.
Dengan asumsi skrip mengirim token di header permintaan yang disebut X-XSRF-TOKEN
, konfigurasikan layanan antiforgery untuk X-XSRF-TOKEN
mencari header:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Contoh berikut menambahkan titik akhir terproteksi yang menulis token permintaan ke JavaScript yang dapat cookiedibaca :
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
Contoh berikut menggunakan JavaScript untuk membuat permintaan AJAX untuk mendapatkan token dan membuat permintaan lain dengan header yang sesuai:
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Catatan
Ketika token antiforgery disediakan di header permintaan dan dalam payload formulir, hanya token di header yang divalidasi.
Antiforgery dengan API Minimal
Minimal APIs
tidak mendukung penggunaan filter yang disertakan (ValidateAntiForgeryToken
, , AutoValidateAntiforgeryToken
IgnoreAntiforgeryToken
), namun, IAntiforgery menyediakan API yang diperlukan untuk memvalidasi permintaan.
Contoh berikut membuat filter yang memvalidasi token antiforgery:
internal static class AntiForgeryExtensions
{
public static TBuilder ValidateAntiforgery<TBuilder>(this TBuilder builder) where TBuilder : IEndpointConventionBuilder
{
return builder.AddEndpointFilter(routeHandlerFilter: async (context, next) =>
{
try
{
var antiForgeryService = context.HttpContext.RequestServices.GetRequiredService<IAntiforgery>();
await antiForgeryService.ValidateRequestAsync(context.HttpContext);
}
catch (AntiforgeryValidationException)
{
return Results.BadRequest("Antiforgery token validation failed.");
}
return await next(context);
});
}
}
Filter kemudian dapat diterapkan ke titik akhir:
app.MapPost("api/upload", (IFormFile name) => Results.Accepted())
.RequireAuthorization()
.ValidateAntiforgery();
Autentikasi Windows dan cookie antiforgery
Saat menggunakan Autentikasi Windows, titik akhir aplikasi harus dilindungi dari serangan CSRF dengan cara yang sama seperti yang dilakukan untuk cookie. Browser secara implisit mengirim konteks autentikasi ke server dan titik akhir perlu dilindungi dari serangan CSRF.
Perluas antiforgery
Jenis ini IAntiforgeryAdditionalDataProvider memungkinkan pengembang untuk memperluas perilaku sistem anti-CSRF dengan melakukan round-tripping data tambahan di setiap token. Metode GetAdditionalData ini dipanggil setiap kali token bidang dihasilkan, dan nilai pengembalian disematkan dalam token yang dihasilkan. Pelaksana dapat mengembalikan tanda waktu, nonce, atau nilai lain lalu memanggil ValidateAdditionalData untuk memvalidasi data ini saat token divalidasi. Nama pengguna klien sudah disematkan dalam token yang dihasilkan, sehingga tidak perlu menyertakan informasi ini. Jika token menyertakan data tambahan tetapi tidak IAntiForgeryAdditionalDataProvider
dikonfigurasi, data tambahan tidak divalidasi.
Sumber Daya Tambahan:
Pemalsuan permintaan lintas situs (juga dikenal sebagai XSRF atau CSRF) adalah serangan terhadap aplikasi yang dihosting web di mana aplikasi web berbahaya dapat memengaruhi interaksi antara browser klien dan aplikasi web yang mempercayai browser tersebut. Serangan ini dimungkinkan karena browser web mengirim beberapa jenis token autentikasi secara otomatis dengan setiap permintaan ke situs web. Bentuk eksploitasi ini juga dikenal sebagai serangan satu klik atau naik sesi karena serangan memanfaatkan sesi yang diautentikasi pengguna sebelumnya.
Contoh serangan CSRF:
Pengguna masuk
www.good-banking-site.example.com
menggunakan autentikasi formulir. Server mengautentikasi pengguna dan mengeluarkan respons yang menyertakan autentikasi cookie. Situs ini rentan terhadap serangan karena mempercayai permintaan apa pun yang diterimanya dengan autentikasi cookieyang valid.Pengguna mengunjungi situs berbahaya,
www.bad-crook-site.example.com
.Situs berbahaya,
www.bad-crook-site.example.com
, berisi formulir HTML yang mirip dengan contoh berikut:<h1>Congratulations! You're a Winner!</h1> <form action="https://good-banking-site.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Perhatikan bahwa posting formulir
action
ke situs yang rentan, bukan ke situs berbahaya. Ini adalah bagian "lintas situs" dari CSRF.Pengguna memilih tombol kirim. Browser membuat permintaan dan secara otomatis menyertakan autentikasi cookie untuk domain yang diminta,
www.good-banking-site.example.com
.Permintaan berjalan di
www.good-banking-site.example.com
server dengan konteks autentikasi pengguna dan dapat melakukan tindakan apa pun yang diizinkan untuk dilakukan oleh pengguna terautentikasi.
Selain skenario di mana pengguna memilih tombol untuk mengirimkan formulir, situs berbahaya dapat:
- Jalankan skrip yang secara otomatis mengirimkan formulir.
- Kirim pengiriman formulir sebagai permintaan AJAX.
- Sembunyikan formulir menggunakan CSS.
Skenario alternatif ini tidak memerlukan tindakan atau input apa pun dari pengguna selain awalnya mengunjungi situs berbahaya.
Menggunakan HTTPS tidak mencegah serangan CSRF. Situs berbahaya dapat mengirim https://www.good-banking-site.com/
permintaan semudah dapat mengirim permintaan yang tidak aman.
Beberapa serangan menargetkan titik akhir yang merespons permintaan GET, dalam hal ini tag gambar dapat digunakan untuk melakukan tindakan. Bentuk serangan ini umum terjadi di situs forum yang mengizinkan gambar tetapi memblokir JavaScript. Aplikasi yang mengubah status pada permintaan GET, di mana variabel atau sumber daya diubah, rentan terhadap serangan berbahaya. Permintaan GET yang mengubah status tidak aman. Praktik terbaik adalah tidak pernah mengubah status pada permintaan GET.
Serangan CSRF dimungkinkan terhadap aplikasi web yang menggunakan cookie untuk autentikasi karena:
- Browser menyimpan cookie yang dikeluarkan oleh aplikasi web.
- Cookie tersimpan mencakup cookie sesi untuk pengguna yang diautentikasi.
- Browser mengirim semua cookie yang terkait dengan domain ke aplikasi web setiap permintaan terlepas dari bagaimana permintaan ke aplikasi dihasilkan dalam browser.
Namun, serangan CSRF tidak terbatas pada mengeksploitasi cookie. Misalnya, autentikasi Dasar dan Hash juga rentan. Setelah pengguna masuk dengan autentikasi Dasar atau Hash, browser secara otomatis mengirim kredensial hingga sesi berakhir.
Dalam konteks ini, sesi mengacu pada sesi sisi klien tempat pengguna diautentikasi. Ini tidak terkait dengan sesi sisi server atau ASP.NET Middleware Sesi Inti.
Pengguna dapat melindungi dari kerentanan CSRF dengan mengambil tindakan pencegahan:
- Keluar dari aplikasi web setelah selesai menggunakannya.
- Hapus cookie browser secara berkala.
Namun, kerentanan CSRF pada dasarnya merupakan masalah dengan aplikasi web, bukan pengguna akhir.
Dasar-dasar autentikasi
CookieAutentikasi berbasis -adalah bentuk autentikasi yang populer. Sistem autentikasi berbasis token semakin populer, terutama untuk Aplikasi Halaman Tunggal (SPAs).
Cookieautentikasi berbasis
Saat pengguna mengautentikasi menggunakan nama pengguna dan kata sandi mereka, mereka mengeluarkan token, yang berisi tiket autentikasi yang dapat digunakan untuk autentikasi dan otorisasi. Token disimpan sebagai cookie yang dikirim dengan setiap permintaan yang dilakukan klien. Menghasilkan dan memvalidasi ini cookie dilakukan oleh Cookie Middleware Autentikasi. Middleware menserialisasikan prinsipal pengguna ke dalam terenkripsi cookie. Pada permintaan berikutnya, middleware memvalidasi cookie, membuat ulang prinsipal, dan menetapkan utama ke HttpContext.User properti .
Autentikasi berbasis token
Saat pengguna diautentikasi, mereka mengeluarkan token (bukan token antiforgery). Token berisi informasi pengguna dalam bentuk klaim atau token referensi yang menunjuk aplikasi ke status pengguna yang dipertahankan di aplikasi. Saat pengguna mencoba mengakses sumber daya yang memerlukan autentikasi, token dikirim ke aplikasi dengan header otorisasi tambahan dalam bentuk token Pembawa. Pendekatan ini membuat aplikasi tanpa status. Dalam setiap permintaan berikutnya, token diteruskan dalam permintaan validasi sisi server. Token ini tidak dienkripsi; dikodekan. Di server, token didekodekan untuk mengakses informasinya. Untuk mengirim token pada permintaan berikutnya, simpan token di penyimpanan lokal browser. Jangan khawatir tentang kerentanan CSRF jika token disimpan di penyimpanan lokal browser. CSRF menjadi perhatian ketika token disimpan dalam cookie. Untuk informasi selengkapnya, lihat sampel kode SPA masalah GitHub menambahkan dua cookie.
Beberapa aplikasi yang dihosting di satu domain
Lingkungan hosting bersama rentan terhadap pembajakan sesi, CSRF masuk, dan serangan lainnya.
Meskipun example1.contoso.net
dan example2.contoso.net
merupakan host yang berbeda, ada hubungan kepercayaan implisit antara host di *.contoso.net
bawah domain. Hubungan kepercayaan implisit ini memungkinkan host yang berpotensi tidak tepercaya untuk memengaruhi cookie satu sama lain (kebijakan asal yang sama yang mengatur permintaan AJAX tidak selalu berlaku untuk cookie HTTP).
Serangan yang mengeksploitasi cookie tepercaya antara aplikasi yang dihosting di domain yang sama dapat dicegah dengan tidak berbagi domain. Saat setiap aplikasi dihosting di domainnya sendiri, tidak ada hubungan kepercayaan implisit cookie untuk dieksploitasi.
Antiforgery dalam ASP.NET Core
Peringatan
ASP.NET Core mengimplementasikan antiforgery menggunakan ASP.NET Core Data Protection. Tumpukan perlindungan data harus dikonfigurasi untuk bekerja di farm server. Untuk informasi selengkapnya, lihat Mengonfigurasi perlindungan data.
Middleware antiforgery ditambahkan ke kontainer injeksi Dependensi ketika salah satu API berikut dipanggil dalam Program.cs
:
FormTagHelper menyuntikkan token anti-pemalsuan ke dalam elemen formulir HTML. Markup berikut dalam Razor file secara otomatis menghasilkan token antiforgery:
<form method="post">
<!-- ... -->
</form>
Demikian pula, IHtmlHelper.BeginForm menghasilkan token antiforgery secara default jika metode formulir bukan GET.
Pembuatan otomatis token antiforgery untuk elemen formulir HTML terjadi ketika <form>
tag berisi method="post"
atribut dan salah satu dari yang berikut ini benar:
- Atribut tindakan kosong (
action=""
). - Atribut tindakan tidak disediakan (
<form method="post">
).
Pembuatan token antiforgeri otomatis untuk elemen formulir HTML dapat dinonaktifkan:
Nonaktifkan token antiforgery secara eksplisit dengan
asp-antiforgery
atribut :<form method="post" asp-antiforgery="false"> <!-- ... --> </form>
Elemen formulir ditolak dari Pembantu Tag dengan menggunakan simbol penolakan Pembantu Tag ! :
<!form method="post"> <!-- ... --> </!form>
FormTagHelper
Hapus dari tampilan.FormTagHelper
dapat dihapus dari tampilan dengan menambahkan direktif berikut ke Razor tampilan:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Catatan
Razor Halaman secara otomatis dilindungi dari XSRF/CSRF. Untuk informasi selengkapnya, lihat XSRF/CSRF dan Razor Pages.
Pendekatan paling umum untuk bertahan dari serangan CSRF adalah menggunakan Pola Token Penyinkron (STP). STP digunakan saat pengguna meminta halaman dengan data formulir:
- Server mengirim token yang terkait dengan pengguna identity saat ini ke klien.
- Klien mengirim kembali token ke server untuk verifikasi.
- Jika server menerima token yang tidak cocok dengan pengguna identityyang diautentikasi, permintaan ditolak.
Token unik dan tidak dapat diprediksi. Token juga dapat digunakan untuk memastikan urutan yang tepat dari serangkaian permintaan (misalnya, memastikan urutan permintaan: halaman 1 > halaman 2 > halaman 3). Semua formulir dalam templat ASP.NET Core MVC dan Razor Pages menghasilkan token antiforgery. Sepasang contoh tampilan berikut menghasilkan token antiforgery:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
Secara eksplisit menambahkan token antiforgery ke <form>
elemen tanpa menggunakan Pembantu Tag dengan pembantu @Html.AntiForgeryToken
HTML :
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Dalam setiap kasus sebelumnya, ASP.NET Core menambahkan bidang formulir tersembunyi yang mirip dengan contoh berikut:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core mencakup tiga filter untuk bekerja dengan token antiforgery:
Antiforgery dengan AddControllers
AddControllers Panggilan tidak mengaktifkan token antiforgery. AddControllersWithViews harus dipanggil untuk memiliki dukungan token antiforgery bawaan.
Beberapa tab browser dan Pola Token Penyinkron
Dengan Pola Token Penyinkron, hanya halaman yang terakhir dimuat yang berisi token antiforgery yang valid. Menggunakan beberapa tab bisa bermasalah. Misalnya, jika pengguna membuka beberapa tab:
- Hanya tab yang terakhir dimuat yang berisi token antiforgery yang valid.
- Permintaan yang dibuat dari tab yang dimuat sebelumnya gagal dengan kesalahan:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Pertimbangkan pola perlindungan CSRF alternatif jika ini menimbulkan masalah.
Mengonfigurasi antiforgery dengan AntiforgeryOptions
Sesuaikan AntiforgeryOptions dalam Program.cs
:
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Atur properti antiforgery Cookie
menggunakan properti kelas , seperti yang CookieBuilder ditunjukkan dalam tabel berikut.
Opsi | Deskripsi |
---|---|
Cookie | Menentukan pengaturan yang digunakan untuk membuat cookie antiforgery. |
FormFieldName | Nama bidang formulir tersembunyi yang digunakan oleh sistem antiforgery untuk merender token antiforgery dalam tampilan. |
HeaderName | Nama header yang digunakan oleh sistem antiforgery. Jika null , sistem hanya mempertimbangkan data formulir. |
SuppressXFrameOptionsHeader | Menentukan apakah akan menekan pembuatan X-Frame-Options header. Secara default, header dihasilkan dengan nilai "SAMEORIGIN". Default ke false . |
Untuk informasi selengkapnya, lihat CookieAuthenticationOptions .
Hasilkan token antiforgery dengan IAntiforgery
IAntiforgery menyediakan API untuk mengonfigurasi fitur antiforgery. IAntiforgery
dapat diminta dalam Program.cs
menggunakan WebApplication.Services. Contoh berikut menggunakan middleware dari halaman aplikasi home untuk menghasilkan token antiforgery dan mengirimkannya dalam respons sebagai cookie:
app.UseRouting();
app.UseAuthorization();
var antiforgery = app.Services.GetRequiredService<IAntiforgery>();
app.Use((context, next) =>
{
var requestPath = context.Request.Path.Value;
if (string.Equals(requestPath, "/", StringComparison.OrdinalIgnoreCase)
|| string.Equals(requestPath, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokenSet = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokenSet.RequestToken!,
new CookieOptions { HttpOnly = false });
}
return next(context);
});
Contoh sebelumnya menetapkan bernama cookie XSRF-TOKEN
. Klien dapat membaca ini cookie dan memberikan nilainya sebagai header yang dilampirkan ke permintaan AJAX. Misalnya, Angular menyertakan perlindungan XSRF bawaan yang membaca nama cookie secara XSRF-TOKEN
default.
Memerlukan validasi antiforgery
Filter tindakan ValidateAntiForgeryToken dapat diterapkan ke tindakan individual, pengontrol, atau secara global. Permintaan yang dibuat untuk tindakan yang menerapkan filter ini diblokir kecuali permintaan menyertakan token antiforgery yang valid:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
Atribut ValidateAntiForgeryToken
memerlukan token untuk permintaan ke metode tindakan yang ditandainya, termasuk permintaan HTTP GET. ValidateAntiForgeryToken
Jika atribut diterapkan di seluruh pengontrol aplikasi, atribut dapat ditimpa dengan IgnoreAntiforgeryToken
atribut .
Memvalidasi token antiforgery secara otomatis hanya untuk metode HTTP yang tidak aman
Alih-alih menerapkan ValidateAntiForgeryToken
atribut secara luas dan kemudian menimpanya dengan IgnoreAntiforgeryToken
atribut, atribut AutoValidateAntiforgeryToken dapat digunakan. Atribut ini berfungsi secara identik dengan ValidateAntiForgeryToken
atribut , kecuali bahwa atribut ini tidak memerlukan token untuk permintaan yang dibuat menggunakan metode HTTP berikut:
- GET
- HEAD
- OPSI
- TRACE
Sebaiknya gunakan AutoValidateAntiforgeryToken
secara luas untuk skenario non-API. Atribut ini memastikan tindakan POST dilindungi secara default. Alternatifnya adalah mengabaikan token antiforgery secara default, kecuali ValidateAntiForgeryToken
diterapkan ke metode tindakan individual. Lebih mungkin dalam skenario ini untuk metode tindakan POST dibiarkan tidak terlindungi secara tidak sengaja, membuat aplikasi rentan terhadap serangan CSRF. Semua POS harus mengirim token antiforgery.
API tidak memiliki mekanisme otomatis untuk mengirim non-bagiancookie token. Implementasi mungkin tergantung pada implementasi kode klien. Beberapa contoh ditunjukkan di bawah ini:
Contoh tingkat kelas:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Contoh global:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Mengambil alih atribut antiforgery global atau pengontrol
Filter IgnoreAntiforgeryToken digunakan untuk menghilangkan kebutuhan token antiforgery untuk tindakan tertentu (atau pengontrol). Saat diterapkan, filter ini mengambil alih ValidateAntiForgeryToken
dan AutoValidateAntiforgeryToken
filter yang ditentukan pada tingkat yang lebih tinggi (secara global atau pada pengontrol).
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Refresh token setelah autentikasi
Token harus di-refresh setelah pengguna diautentikasi dengan mengalihkan pengguna ke halaman tampilan atau Razor Halaman.
JavaScript, AJAX, dan SPAs
Dalam aplikasi tradisional berbasis HTML, token antiforgery diteruskan ke server menggunakan bidang formulir tersembunyi. Di aplikasi dan SPAs berbasis JavaScript modern, banyak permintaan dibuat secara terprogram. Permintaan AJAX ini dapat menggunakan teknik lain (seperti header permintaan atau cookie) untuk mengirim token.
Jika cookie digunakan untuk menyimpan token autentikasi dan untuk mengautentikasi permintaan API di server, CSRF adalah masalah potensial. Jika penyimpanan lokal digunakan untuk menyimpan token, kerentanan CSRF mungkin dimitigasi karena nilai dari penyimpanan lokal tidak dikirim secara otomatis ke server dengan setiap permintaan. Menggunakan penyimpanan lokal untuk menyimpan token antiforgery pada klien dan mengirim token sebagai header permintaan adalah pendekatan yang direkomendasikan.
JavaScript
Menggunakan JavaScript dengan tampilan, token dapat dibuat menggunakan layanan dari dalam tampilan. IAntiforgery Masukkan layanan ke dalam tampilan dan panggil GetAndStoreTokens:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
@{
ViewData["Title"] = "JavaScript";
var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}
<input id="RequestVerificationToken" type="hidden" value="@requestToken" />
<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>
@section Scripts {
<script>
document.addEventListener("DOMContentLoaded", () => {
const resultElement = document.getElementById("result");
document.getElementById("button").addEventListener("click", async () => {
const response = await fetch("@Url.Action("FetchEndpoint")", {
method: "POST",
headers: {
RequestVerificationToken:
document.getElementById("RequestVerificationToken").value
}
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
});
});
</script>
}
Contoh sebelumnya menggunakan JavaScript untuk membaca nilai bidang tersembunyi untuk header AJAX POST.
Pendekatan ini menghilangkan kebutuhan untuk berurusan langsung dengan pengaturan cookie dari server atau membacanya dari klien. Namun, ketika menyuntikkan layanan tidak dimungkinkan IAntiforgery , JavaScript juga dapat mengakses token dalam cookie, diperoleh dari permintaan tambahan ke server (biasanya same-origin
), dan menggunakan cookiekonten 's untuk membuat header dengan nilai token.
Dengan asumsi skrip mengirim token di header permintaan yang disebut X-XSRF-TOKEN
, konfigurasikan layanan antiforgery untuk X-XSRF-TOKEN
mencari header:
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Contoh berikut menambahkan titik akhir terproteksi yang akan menulis token permintaan ke JavaScript yang dapat cookiedibaca :
app.UseAuthorization();
app.MapGet("antiforgery/token", (IAntiforgery forgeryService, HttpContext context) =>
{
var tokens = forgeryService.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken!,
new CookieOptions { HttpOnly = false });
return Results.Ok();
}).RequireAuthorization();
Contoh berikut menggunakan JavaScript untuk membuat permintaan AJAX untuk mendapatkan token dan membuat permintaan lain dengan header yang sesuai:
var response = await fetch("/antiforgery/token", {
method: "GET",
headers: { "Authorization": authorizationToken }
});
if (response.ok) {
// https://developer.mozilla.org/docs/web/api/document/cookie
const xsrfToken = document.cookie
.split("; ")
.find(row => row.startsWith("XSRF-TOKEN="))
.split("=")[1];
response = await fetch("/JavaScript/FetchEndpoint", {
method: "POST",
headers: { "X-XSRF-TOKEN": xsrfToken, "Authorization": authorizationToken }
});
if (response.ok) {
resultElement.innerText = await response.text();
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
} else {
resultElement.innerText = `Request Failed: ${response.status}`
}
Autentikasi Windows dan cookie antiforgery
Saat menggunakan Autentikasi Windows, titik akhir aplikasi harus dilindungi dari serangan CSRF dengan cara yang sama seperti yang dilakukan untuk cookie. Browser secara implisit mengirim konteks autentikasi ke server sehingga titik akhir perlu dilindungi dari serangan CSRF.
Perluas antiforgery
Jenis ini IAntiforgeryAdditionalDataProvider memungkinkan pengembang untuk memperluas perilaku sistem anti-CSRF dengan melakukan round-tripping data tambahan di setiap token. Metode GetAdditionalData ini dipanggil setiap kali token bidang dihasilkan, dan nilai pengembalian disematkan dalam token yang dihasilkan. Pelaksana dapat mengembalikan tanda waktu, nonce, atau nilai lain lalu memanggil ValidateAdditionalData untuk memvalidasi data ini saat token divalidasi. Nama pengguna klien sudah disematkan dalam token yang dihasilkan, sehingga tidak perlu menyertakan informasi ini. Jika token menyertakan data tambahan tetapi tidak IAntiForgeryAdditionalDataProvider
dikonfigurasi, data tambahan tidak divalidasi.
Sumber Daya Tambahan:
Pemalsuan permintaan lintas situs (juga dikenal sebagai XSRF atau CSRF) adalah serangan terhadap aplikasi yang dihosting web di mana aplikasi web berbahaya dapat memengaruhi interaksi antara browser klien dan aplikasi web yang mempercayai browser tersebut. Serangan ini dimungkinkan karena browser web mengirim beberapa jenis token autentikasi secara otomatis dengan setiap permintaan ke situs web. Bentuk eksploitasi ini juga dikenal sebagai serangan satu klik atau naik sesi karena serangan memanfaatkan sesi yang diautentikasi pengguna sebelumnya.
Contoh serangan CSRF:
Pengguna masuk
www.good-banking-site.example.com
menggunakan autentikasi formulir. Server mengautentikasi pengguna dan mengeluarkan respons yang menyertakan autentikasi cookie. Situs ini rentan terhadap serangan karena mempercayai permintaan apa pun yang diterimanya dengan autentikasi cookieyang valid.Pengguna mengunjungi situs berbahaya,
www.bad-crook-site.example.com
.Situs berbahaya,
www.bad-crook-site.example.com
, berisi formulir HTML yang mirip dengan contoh berikut:<h1>Congratulations! You're a Winner!</h1> <form action="https://good-banking-site.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw" /> <input type="hidden" name="Amount" value="1000000" /> <input type="submit" value="Click to collect your prize!" /> </form>
Perhatikan bahwa posting formulir
action
ke situs yang rentan, bukan ke situs berbahaya. Ini adalah bagian "lintas situs" dari CSRF.Pengguna memilih tombol kirim. Browser membuat permintaan dan secara otomatis menyertakan autentikasi cookie untuk domain yang diminta,
www.good-banking-site.example.com
.Permintaan berjalan di
www.good-banking-site.example.com
server dengan konteks autentikasi pengguna dan dapat melakukan tindakan apa pun yang diizinkan untuk dilakukan oleh pengguna terautentikasi.
Selain skenario di mana pengguna memilih tombol untuk mengirimkan formulir, situs berbahaya dapat:
- Jalankan skrip yang secara otomatis mengirimkan formulir.
- Kirim pengiriman formulir sebagai permintaan AJAX.
- Sembunyikan formulir menggunakan CSS.
Skenario alternatif ini tidak memerlukan tindakan atau input apa pun dari pengguna selain awalnya mengunjungi situs berbahaya.
Menggunakan HTTPS tidak mencegah serangan CSRF. Situs berbahaya dapat mengirim https://www.good-banking-site.com/
permintaan semudah dapat mengirim permintaan yang tidak aman.
Beberapa serangan menargetkan titik akhir yang merespons permintaan GET, dalam hal ini tag gambar dapat digunakan untuk melakukan tindakan. Bentuk serangan ini umum terjadi di situs forum yang mengizinkan gambar tetapi memblokir JavaScript. Aplikasi yang mengubah status pada permintaan GET, di mana variabel atau sumber daya diubah, rentan terhadap serangan berbahaya. Permintaan GET yang mengubah status tidak aman. Praktik terbaik adalah tidak pernah mengubah status pada permintaan GET.
Serangan CSRF dimungkinkan terhadap aplikasi web yang menggunakan cookie untuk autentikasi karena:
- Browser menyimpan cookie yang dikeluarkan oleh aplikasi web.
- Cookie tersimpan mencakup cookie sesi untuk pengguna yang diautentikasi.
- Browser mengirim semua cookie yang terkait dengan domain ke aplikasi web setiap permintaan terlepas dari bagaimana permintaan ke aplikasi dihasilkan dalam browser.
Namun, serangan CSRF tidak terbatas pada mengeksploitasi cookie. Misalnya, autentikasi Dasar dan Hash juga rentan. Setelah pengguna masuk dengan autentikasi Dasar atau Hash, browser secara otomatis mengirim kredensial hingga sesi berakhir.
Dalam konteks ini, sesi mengacu pada sesi sisi klien tempat pengguna diautentikasi. Ini tidak terkait dengan sesi sisi server atau ASP.NET Middleware Sesi Inti.
Pengguna dapat melindungi dari kerentanan CSRF dengan mengambil tindakan pencegahan:
- Keluar dari aplikasi web setelah selesai menggunakannya.
- Hapus cookie browser secara berkala.
Namun, kerentanan CSRF pada dasarnya merupakan masalah dengan aplikasi web, bukan pengguna akhir.
Dasar-dasar autentikasi
CookieAutentikasi berbasis -adalah bentuk autentikasi yang populer. Sistem autentikasi berbasis token semakin populer, terutama untuk Aplikasi Halaman Tunggal (SPAs).
Cookieautentikasi berbasis
Saat pengguna mengautentikasi menggunakan nama pengguna dan kata sandi mereka, mereka mengeluarkan token, yang berisi tiket autentikasi yang dapat digunakan untuk autentikasi dan otorisasi. Token disimpan sebagai cookie yang dikirim dengan setiap permintaan yang dilakukan klien. Menghasilkan dan memvalidasi ini cookie dilakukan oleh Cookie Middleware Autentikasi. Middleware menserialisasikan prinsipal pengguna ke dalam terenkripsi cookie. Pada permintaan berikutnya, middleware memvalidasi cookie, membuat ulang prinsipal, dan menetapkan utama ke HttpContext.User properti .
Autentikasi berbasis token
Saat pengguna diautentikasi, mereka mengeluarkan token (bukan token antiforgery). Token berisi informasi pengguna dalam bentuk klaim atau token referensi yang menunjuk aplikasi ke status pengguna yang dipertahankan di aplikasi. Saat pengguna mencoba mengakses sumber daya yang memerlukan autentikasi, token dikirim ke aplikasi dengan header otorisasi tambahan dalam bentuk token Pembawa. Pendekatan ini membuat aplikasi tanpa status. Dalam setiap permintaan berikutnya, token diteruskan dalam permintaan validasi sisi server. Token ini tidak dienkripsi; dikodekan. Di server, token didekodekan untuk mengakses informasinya. Untuk mengirim token pada permintaan berikutnya, simpan token di penyimpanan lokal browser. Jangan khawatir tentang kerentanan CSRF jika token disimpan di penyimpanan lokal browser. CSRF menjadi perhatian ketika token disimpan dalam cookie. Untuk informasi selengkapnya, lihat sampel kode SPA masalah GitHub menambahkan dua cookie.
Beberapa aplikasi yang dihosting di satu domain
Lingkungan hosting bersama rentan terhadap pembajakan sesi, CSRF masuk, dan serangan lainnya.
Meskipun example1.contoso.net
dan example2.contoso.net
merupakan host yang berbeda, ada hubungan kepercayaan implisit antara host di *.contoso.net
bawah domain. Hubungan kepercayaan implisit ini memungkinkan host yang berpotensi tidak tepercaya untuk memengaruhi cookie satu sama lain (kebijakan asal yang sama yang mengatur permintaan AJAX tidak selalu berlaku untuk cookie HTTP).
Serangan yang mengeksploitasi cookie tepercaya antara aplikasi yang dihosting di domain yang sama dapat dicegah dengan tidak berbagi domain. Saat setiap aplikasi dihosting di domainnya sendiri, tidak ada hubungan kepercayaan implisit cookie untuk dieksploitasi.
konfigurasi antiforgery ASP.NET Core
Peringatan
ASP.NET Core mengimplementasikan antiforgery menggunakan ASP.NET Core Data Protection. Tumpukan perlindungan data harus dikonfigurasi untuk bekerja di farm server. Untuk informasi selengkapnya, lihat Mengonfigurasi perlindungan data.
Middleware antiforgery ditambahkan ke kontainer injeksi Dependensi ketika salah satu API berikut dipanggil dalam Startup.ConfigureServices
:
Dalam ASP.NET Core 2.0 atau yang lebih baru, FormTagHelper menyuntikkan token antiforgery ke dalam elemen bentuk HTML. Markup berikut dalam Razor file secara otomatis menghasilkan token antiforgery:
<form method="post">
...
</form>
Demikian pula, IHtmlHelper.BeginForm menghasilkan token antiforgery secara default jika metode formulir bukan GET.
Pembuatan otomatis token antiforgery untuk elemen formulir HTML terjadi ketika <form>
tag berisi method="post"
atribut dan salah satu dari yang berikut ini benar:
- Atribut tindakan kosong (
action=""
). - Atribut tindakan tidak disediakan (
<form method="post">
).
Pembuatan token antiforgeri otomatis untuk elemen formulir HTML dapat dinonaktifkan:
Nonaktifkan token antiforgery secara eksplisit dengan
asp-antiforgery
atribut :<form method="post" asp-antiforgery="false"> ... </form>
Elemen formulir ditolak dari Pembantu Tag dengan menggunakan simbol penolakan Pembantu Tag ! :
<!form method="post"> ... </!form>
FormTagHelper
Hapus dari tampilan.FormTagHelper
dapat dihapus dari tampilan dengan menambahkan direktif berikut ke Razor tampilan:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Catatan
Razor Halaman secara otomatis dilindungi dari XSRF/CSRF. Untuk informasi selengkapnya, lihat XSRF/CSRF dan Razor Pages.
Pendekatan paling umum untuk bertahan dari serangan CSRF adalah menggunakan Pola Token Penyinkron (STP). STP digunakan saat pengguna meminta halaman dengan data formulir:
- Server mengirim token yang terkait dengan pengguna identity saat ini ke klien.
- Klien mengirim kembali token ke server untuk verifikasi.
- Jika server menerima token yang tidak cocok dengan pengguna identityyang diautentikasi, permintaan ditolak.
Token unik dan tidak dapat diprediksi. Token juga dapat digunakan untuk memastikan urutan yang tepat dari serangkaian permintaan (misalnya, memastikan urutan permintaan: halaman 1 > halaman 2 > halaman 3). Semua formulir dalam templat ASP.NET Core MVC dan Razor Pages menghasilkan token antiforgery. Sepasang contoh tampilan berikut menghasilkan token antiforgery:
<form asp-controller="Todo" asp-action="Create" method="post">
...
</form>
@using (Html.BeginForm("Create", "Todo"))
{
...
}
Secara eksplisit menambahkan token antiforgery ke <form>
elemen tanpa menggunakan Pembantu Tag dengan pembantu @Html.AntiForgeryToken
HTML :
<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
Dalam setiap kasus sebelumnya, ASP.NET Core menambahkan bidang formulir tersembunyi yang mirip dengan contoh berikut:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core mencakup tiga filter untuk bekerja dengan token antiforgery:
Opsi antiforgery
Sesuaikan AntiforgeryOptions dalam Startup.ConfigureServices
:
services.AddAntiforgery(options =>
{
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Atur properti antiforgery Cookie
menggunakan properti kelas , seperti yang CookieBuilder ditunjukkan dalam tabel berikut.
Opsi | Deskripsi |
---|---|
Cookie | Menentukan pengaturan yang digunakan untuk membuat cookie antiforgery. |
FormFieldName | Nama bidang formulir tersembunyi yang digunakan oleh sistem antiforgery untuk merender token antiforgery dalam tampilan. |
HeaderName | Nama header yang digunakan oleh sistem antiforgery. Jika null , sistem hanya mempertimbangkan data formulir. |
SuppressXFrameOptionsHeader | Menentukan apakah akan menekan pembuatan X-Frame-Options header. Secara default, header dihasilkan dengan nilai "SAMEORIGIN". Default ke false . |
Untuk informasi selengkapnya, lihat CookieAuthenticationOptions .
Mengonfigurasi fitur antiforgery dengan IAntiforgery
IAntiforgery menyediakan API untuk mengonfigurasi fitur antiforgery. IAntiforgery
dapat diminta dalam Configure
metode Startup
kelas .
Dalam contoh berikut:
- Middleware dari halaman aplikasi home digunakan untuk menghasilkan token antiforgery dan mengirimkannya dalam respons sebagai cookie.
- Token permintaan dikirim sebagai JavaScript-readable cookie dengan konvensi penamaan Angular default yang dijelaskan di bagian AngularJS .
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
Memerlukan validasi antiforgery
ValidateAntiForgeryToken adalah filter tindakan yang dapat diterapkan ke tindakan individual, pengontrol, atau secara global. Permintaan yang dibuat untuk tindakan yang menerapkan filter ini diblokir kecuali permintaan menyertakan token antiforgery yang valid.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result =
await _userManager.RemoveLoginAsync(
user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
Atribut ValidateAntiForgeryToken
memerlukan token untuk permintaan ke metode tindakan yang ditandainya, termasuk permintaan HTTP GET. ValidateAntiForgeryToken
Jika atribut diterapkan di seluruh pengontrol aplikasi, atribut dapat ditimpa dengan IgnoreAntiforgeryToken
atribut .
Catatan
ASP.NET Core tidak mendukung penambahan token antiforgery ke permintaan GET secara otomatis.
Memvalidasi token antiforgery secara otomatis hanya untuk metode HTTP yang tidak aman
ASP.NET Core tidak menghasilkan token antiforgery untuk metode HTTP yang aman (GET, HEAD, OPTIONS, dan TRACE). Alih-alih menerapkan ValidateAntiForgeryToken
atribut secara luas dan kemudian menimpanya dengan IgnoreAntiforgeryToken
atribut, atribut AutoValidateAntiforgeryToken dapat digunakan. Atribut ini berfungsi secara identik dengan ValidateAntiForgeryToken
atribut , kecuali bahwa atribut ini tidak memerlukan token untuk permintaan yang dibuat menggunakan metode HTTP berikut:
- GET
- HEAD
- OPSI
- TRACE
Sebaiknya gunakan AutoValidateAntiforgeryToken
secara luas untuk skenario non-API. Atribut ini memastikan tindakan POST dilindungi secara default. Alternatifnya adalah mengabaikan token antiforgery secara default, kecuali ValidateAntiForgeryToken
diterapkan ke metode tindakan individual. Lebih mungkin dalam skenario ini untuk metode tindakan POST dibiarkan tidak terlindungi secara tidak sengaja, membuat aplikasi rentan terhadap serangan CSRF. Semua POS harus mengirim token antiforgery.
API tidak memiliki mekanisme otomatis untuk mengirim non-bagiancookie token. Implementasi mungkin tergantung pada implementasi kode klien. Beberapa contoh ditunjukkan di bawah ini:
Contoh tingkat kelas:
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
Contoh global:
services.AddControllersWithViews(options =>
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
Mengambil alih atribut antiforgery global atau pengontrol
Filter IgnoreAntiforgeryToken digunakan untuk menghilangkan kebutuhan token antiforgery untuk tindakan tertentu (atau pengontrol). Saat diterapkan, filter ini mengambil alih ValidateAntiForgeryToken
dan AutoValidateAntiforgeryToken
filter yang ditentukan pada tingkat yang lebih tinggi (secara global atau pada pengontrol).
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
{
// no antiforgery token required
}
}
Refresh token setelah autentikasi
Token harus di-refresh setelah pengguna diautentikasi dengan mengalihkan pengguna ke halaman tampilan atau Razor Halaman.
JavaScript, AJAX, dan SPAs
Dalam aplikasi tradisional berbasis HTML, token antiforgery diteruskan ke server menggunakan bidang formulir tersembunyi. Di aplikasi dan SPAs berbasis JavaScript modern, banyak permintaan dibuat secara terprogram. Permintaan AJAX ini dapat menggunakan teknik lain (seperti header permintaan atau cookie) untuk mengirim token.
Jika cookie digunakan untuk menyimpan token autentikasi dan untuk mengautentikasi permintaan API di server, CSRF adalah masalah potensial. Jika penyimpanan lokal digunakan untuk menyimpan token, kerentanan CSRF mungkin dimitigasi karena nilai dari penyimpanan lokal tidak dikirim secara otomatis ke server dengan setiap permintaan. Menggunakan penyimpanan lokal untuk menyimpan token antiforgery pada klien dan mengirim token sebagai header permintaan adalah pendekatan yang direkomendasikan.
JavaScript
Menggunakan JavaScript dengan tampilan, token dapat dibuat menggunakan layanan dari dalam tampilan. IAntiforgery Masukkan layanan ke dalam tampilan dan panggil GetAndStoreTokens:
@{
ViewData["Title"] = "AJAX Demo";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
<input type="hidden" id="RequestVerificationToken"
name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<div class="row">
<p><input type="button" id="antiforgery" value="Antiforgery"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == XMLHttpRequest.DONE) {
if (xhttp.status == 200) {
alert(xhttp.responseText);
} else {
alert('There was an error processing the AJAX request.');
}
}
};
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("antiforgery").onclick = function () {
xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
xhttp.setRequestHeader("RequestVerificationToken",
document.getElementById('RequestVerificationToken').value);
xhttp.send();
}
});
</script>
</div>
Pendekatan ini menghilangkan kebutuhan untuk berurusan langsung dengan pengaturan cookie dari server atau membacanya dari klien.
Contoh sebelumnya menggunakan JavaScript untuk membaca nilai bidang tersembunyi untuk header AJAX POST.
JavaScript juga dapat mengakses token dalam cookie dan menggunakan cookiekonten 's untuk membuat header dengan nilai token.
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
Dengan asumsi permintaan skrip untuk mengirim token di header yang disebut X-CSRF-TOKEN
, konfigurasikan layanan antiforgery untuk X-CSRF-TOKEN
mencari header:
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
Contoh berikut menggunakan JavaScript untuk membuat permintaan AJAX dengan header yang sesuai:
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var csrfToken = getCookie("CSRF-TOKEN");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 204) {
alert('Todo item is created successfully.');
} else {
alert('There was an error processing the AJAX request.');
}
}
};
xhttp.open('POST', '/api/items', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "name": "Learn C#" }));
AngularJS
AngularJS menggunakan konvensi untuk mengatasi CSRF. Jika server mengirim cookie dengan nama XSRF-TOKEN
, layanan AngularJS $http
menambahkan cookie nilai ke header saat mengirim permintaan ke server. Proses ini bersifat otomatis. Klien tidak perlu mengatur header secara eksplisit. Nama header adalah X-XSRF-TOKEN
. Server harus mendeteksi header ini dan memvalidasi isinya.
Agar ASP.NET Core API berfungsi dengan konvensi ini dalam startup aplikasi Anda:
- Konfigurasikan aplikasi Anda untuk menyediakan token dalam yang cookie disebut
XSRF-TOKEN
. - Konfigurasikan layanan antiforgery untuk mencari header bernama
X-XSRF-TOKEN
, yang merupakan nama header default Angular untuk mengirim token XSRF.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
}
Catatan
Ketika token antiforgery disediakan di header permintaan dan dalam payload formulir, hanya token di header yang divalidasi.
Autentikasi Windows dan cookie antiforgery
Saat menggunakan Autentikasi Windows, titik akhir aplikasi harus dilindungi dari serangan CSRF dengan cara yang sama seperti yang dilakukan untuk cookie. Browser secara implisit mengirim konteks autentikasi ke server sehingga titik akhir perlu dilindungi dari serangan CSRF.
Perluas antiforgery
Jenis ini IAntiforgeryAdditionalDataProvider memungkinkan pengembang untuk memperluas perilaku sistem anti-CSRF dengan melakukan round-tripping data tambahan di setiap token. Metode GetAdditionalData ini dipanggil setiap kali token bidang dihasilkan, dan nilai pengembalian disematkan dalam token yang dihasilkan. Pelaksana dapat mengembalikan tanda waktu, nonce, atau nilai lain lalu memanggil ValidateAdditionalData untuk memvalidasi data ini saat token divalidasi. Nama pengguna klien sudah disematkan dalam token yang dihasilkan, sehingga tidak perlu menyertakan informasi ini. Jika token menyertakan data tambahan tetapi tidak IAntiForgeryAdditionalDataProvider
dikonfigurasi, data tambahan tidak divalidasi.
Sumber Daya Tambahan:
ASP.NET Core