Bao ve CSRF tu dong dua tren Fetch Metadata header trong ASP.NET Core .NET 11 Preview 6

Day la bai thu sau trong series Kham pha ban preview cua .NET 11.

Trong bai nay, chung ta tim hieu tinh nang bao ve Cross-Site Request Forgery (CSRF) moi duoc them vao ASP.NET Core trong .NET 11 Preview 6. Tinh nang nay dua tren Fetch Metadata HTTP header, thay vi chi su dung cac anti-CSRF token theo mo hinh truyen thong cua cac phien ban .NET Core truoc day.

Truoc tien, bai viet giai thich CSRF la gi, ASP.NET Core dang bao ve ung dung nhu the nao va vi sao co the ap dung cach tiep can moi. Sau do, chung ta xem lai Fetch Metadata header, cach tinh nang moi hoat dong trong ASP.NET Core tu .NET 11 Preview 6, cung nhu mot phan tich ngan ve ma nguon ben duoi. Cuoi cung, bai viet chi ra rang tinh nang moi chua thuc su giup ich neu ung dung dang su dung MVC hoac Razor Pages.

CSRF la gi?

Cross-Site Request Forgery la mot dang tan cong trong do website doc hai tao ra request den ung dung web cua ban, khien ung dung xu ly request do nhu mot request hop le tu nguoi dung.

Vi du kinh dien la mot ung dung ngan hang truc tuyen luu token xac thuc trong cookie. Day la cach lam pho bien va cung la cach ASP.NET Core Identity hoat dong mac dinh. Sau khi nguoi dung dang nhap, trinh duyet tu dong gui cookie kem theo moi request khi nguoi dung dieu huong trong website.

Gia su ung dung ngan hang co mot trang cho phep chuyen tien sang tai khoan khac bang request POST. Nguoi dung phai dang nhap moi co the truy cap bieu mau, nhung bieu mau chi can chua so tien va tai khoan nhan. Khi bam Submit, trinh duyet gui request POST va giao dich duoc thuc hien.

Sau khi truy cap ung dung ngan hang, nguoi dung vo tinh mo mot website doc hai. Ke tan cong da nhung vao website do mot bieu mau gui request POST den ung dung ngan hang. Bieu mau nay giong bieu mau chuyen tien hop le, nhung yeu cau chuyen 1.000 USD vao tai khoan cua ke tan cong. Vi nguoi dung van dang nhap, trinh duyet tu dong gui cookie xac thuc. Ung dung ngan hang nhin thay request hop le va thuc hien giao dich. Day la mot cuoc tan cong CSRF.

Cookie SameSite cung cap mot lop phong ve tot, vi trinh duyet co the tu choi gui cookie xac thuc trong tinh huong tren. Tuy nhien, khong phai ung dung nao cung co the bat SameSite cookie. Giai phap pho bien nhat tu truoc den nay la su dung synchronizer token.

Co che bao ve CSRF hien tai cua ASP.NET Core

ASP.NET Core da ho tro san co bao ve CSRF tu it nhat ASP.NET Core 2.0. Co che nay da duoc cai tien qua nhieu nam, nhung cot loi van dua tren synchronizer token pattern:

  1. Mot token duy nhat, gan voi nguoi dung, duoc luu trong cookie.
  2. Mot token duy nhat khac, duoc tao dua tren nguoi dung, duoc them vao moi bieu mau do ung dung render.
  3. Khi bieu mau duoc gui den server, server so sanh hai token va kiem tra tinh hop le. Neu token khong hop le, request bi tu choi va khong duoc xu ly.

Trong cac phien ban ASP.NET Core gan day, antiforgery token duoc tu dong them vao moi bieu mau POST duoc render bang Razor. Ngoai ra, AntiforgeryMiddleware cung duoc tu dong them vao pipeline neu ban goi AddAntiforgery(), AddMvc() hoac phuong thuc tuong tu tren DI container.

Khi server nhan request, middleware doc IAntiforgeryMetadata gan voi endpoint da chon, sau do goi IAntiforgery.ValidateRequestAsync(). Mac dinh, phuong thuc nay thuc hien synchronizer token pattern neu tren.

Co che nay nhin chung hoat dong tot va da duoc su dung hieu qua trong gan mot thap ky. Vay tai sao can thay doi?

Vi sao ASP.NET Core can tinh nang anti-CSRF moi?

Synchronizer token van hoat dong tot trong phan lon truong hop, nhung co mot so kho khan.

Truoc het, co che antiforgery phu thuoc vao Data Protection system cua ASP.NET Core. Day la he thong co trang thai, tao them chi phi van hanh vi du lieu can duoc bao ve va luu tru can than. Trong mo hinh web farm, hoac pho bien hon hien nay la Kubernetes, cac replica con phai chia se an toan Data Protection key. Co cac cach tieu chuan de thuc hien viec nay, nhung qua trinh cau hinh co the khong don gian.

Van de tiep theo la chi trang duoc tai gan nhat tren website su dung antiforgery token moi chua token hop le. Neu nguoi dung mo them mot tab, tab ban dau co the khong con hop le. Day la han che dang ke doi voi mot tinh nang co ban cua trinh duyet.

Cuoi cung la chi phi hieu nang. Du Data Protection API da nhanh hon qua tung nam, he thong van phai ma hoa, giai ma hoac bam du lieu trong moi request. Chi phi nay khong qua lon, nhung se tot hon neu co the loai bo.

Neu khong co mot tien bo moi trong trinh duyet, cac han che tren co the van chap nhan duoc. Tien bo do chinh la Fetch Metadata HTTP header.

On lai Fetch Metadata HTTP header

Fetch Metadata HTTP header la tap hop gom 4 header bao mat, duoc ho tro rong rai trong cac trinh duyet tu nam 2023. Chung duoc gui kem theo request den server, cung cap them thong tin ve nguon goc va muc dich cua request, dong thoi khong the bi dat bang JavaScript.

  • Sec-Fetch-Dest: cho biet response se duoc dung cho muc dich gi, vi du image, style, document hoac empty neu duoc dung trong JavaScript.
  • Sec-Fetch-Site: cho biet request den tu dau: cross-site, same-site, same-origin hoac none. Gia tri none thuong xuat hien khi nguoi dung bam bookmark hoac tu nhap URL.
  • Sec-Fetch-Mode: cho biet request su dung che do nao: same-origin, cors, no-cors, websocket hoac navigate neu day la dieu huong cap cao nhat.
  • Sec-Fetch-User: cho biet hanh dong co duoc khoi tao boi nguoi dung hay khong.

Mot request dieu huong cap cao nhat ban dau co the nhu sau:

Sec-Fetch-Dest: document<br>Sec-Fetch-Mode: navigate<br>Sec-Fetch-Site: none<br>Sec-Fetch-User: ?1

Mot hinh anh tai tu CDN co the co cac header:

Sec-Fetch-Dest: image<br>Sec-Fetch-Mode: no-cors<br>Sec-Fetch-Site: cross-site

Trong khi do, JavaScript goi fetch() den mot website ben thu ba co the tao ra:

Sec-Fetch-Dest: empty<br>Sec-Fetch-Mode: cors<br>Sec-Fetch-Site: cross-origin

Voi cac header nay co san trong cac trinh duyet hien dai, ASP.NET Core co the ap dung mot thuat toan anti-CSRF don gian hon.

Cap nhat thuat toan anti-CSRF trong ASP.NET Core

Thuat toan moi trong ASP.NET Core co ve duoc lay cam hung tu thuat toan tuong duong trong Go 1.25. Khi duoc bat, thuat toan hoat dong theo cac buoc sau:

  1. Request co su dung HTTP verb an toan hay khong? Cac verb an toan gom GET, HEAD, OPTIONS, TRACE va QUERY. Neu co, request duoc cho phep.
  2. Header Sec-Fetch-Site co gia tri same-origin hoac none khong? Neu co, request duoc cho phep.
  3. Header Origin co ton tai khong? Neu co, he thong kiem tra endpoint co CORS policy hay khong. Neu gia tri Origin nam trong danh sach cho phep, request duoc cho phep. Tuy nhien, cau hinh cho phep moi origin se khong duoc chap nhan trong buoc kiem tra nay.
  4. Header Sec-Fetch-Site co ton tai khong? Neu co, gia tri luc nay se la cross-origin hoac same-site, vi cac truong hop khac da duoc xu ly. Request bi tu choi.
  5. Header Origin co ton tai khong? Neu co, he thong so sanh no voi header Host. Neu trung khop, request duoc cho phep; neu khac, request bi tu choi.
  6. Khong co Sec-Fetch-Site va cung khong co Origin: dieu nay cho thay request khong den tu trinh duyet. Vi CSRF la tan cong dua tren trinh duyet, request duoc cho phep.

Thuat toan nay duoc cai dat trong service DefaultCsrfProtection, la implementation mac dinh cua interface moi ICsrfProtection trong .NET 11. CsrfProtectionMiddleware su dung service nay de goi thuat toan CSRF, tru khi endpoint da chu dong tat anti-CSRF.

Middleware nay duoc tu dong them vao pipeline cua WebApplicationBuilder, vi vay ban khong can tu cau hinh truc tiep.

Can phan biet co che moi voi co che CSRF dua tren token. IAntiforgery, AntiforgeryMiddleware va UseAntiforgery() van lien quan den synchronizer token implementation, khong phai Fetch Metadata implementation moi.

CsrfProtectionMiddleware khong lap tuc tu choi request. Thay vao do, middleware ghi lai ket qua allowed hoac denied vao request, sau do de cac thanh phan tiep theo quyet dinh co thuc thi hay khong. Cac thanh phan nay gom:

  • MVC action
  • Minimal API doc form data
  • Endpoint Blazor static server-side rendering (SSR)
  • Bat ky endpoint nao doc request body duoi dang form

Khong phai endpoint nao cung phat sinh loi anti-CSRF khi middleware tra ve denied. Request chi thuc su de bi tan cong CSRF khi dong thoi:

  1. Duoc gui tu trinh duyet.
  2. Su dung Cookie authentication.
  3. Su dung du lieu dang <form>.

Neu request doc body dang JSON thi thong thuong khong de bi CSRF. Neu request duoc gui bang curl thay vi trinh duyet thi cung khong de bi CSRF. Vi vay, de tranh false positive, framework chi ra quyet dinh cuoi cung khi co hanh dong co nguy co, chang han doc request body dang form.

Cap nhat ung dung de ho tro middleware moi

Tin tot la phan lon ung dung .NET 11 co le khong can thay doi gi. He thong moi duoc thiet ke de ket noi muot ma voi co che anti-CSRF hien co. Moi lenh goi DisableAntiforgery() va moi attribute [IgnoreAntiforgeryToken] van duoc ton trong nhu truoc.

Neu ung dung dang goi UseAntiforgery(), ban co the muon go bo lenh nay. Lenh do them middleware validation dua tren token vao pipeline sau CsrfProtectionMiddleware. Middleware cu se ghi de ket qua cua co che moi, khien ung dung tiep tuc hoat dong gan nhu khong co thay doi. Muon su dung hanh vi moi, hay xoa cac lenh goi UseAntiforgery().

Neu dung MVC hoac Razor Pages, hien tai khong co cach don gian de chi su dung co che moi. Phan sau se giai thich chi tiet hon.

Truong hop de gap nhat khi nang cap len .NET 11 la request cross-origin hop le nhung bi mac dinh chan. Co hai cach xu ly:

  1. Tat CSRF cho endpoint do bang DisableAntiforgery() voi Minimal API, hoac them [IgnoreAntiforgeryToken] voi MVC/Razor Pages.
  2. Them origin cu the vao danh sach CORS origin duoc cho phep.

Vi du, ung dung chay tai https://example.com can chap nhan form post tu https://shop.example.com:

var builder = WebApplication.CreateBuilder(args);<br>var app = builder.Build();<br><br>// Endpoint dung [FromForm] nen yeu cau CSRF protection<br>app.MapPost("/success", ([FromForm] OrderId id, IOrderService order)<br> => order.Handle(id));<br><br>app.Run();

Voi cau hinh tren, request den /success se nhan 400 Bad Request khi anti-CSRF kich hoat. De cho phep request tu shop.example.com, can cau hinh CORS:

var builder = WebApplication.CreateBuilder(args);<br><br>builder.Services.AddCors(options =><br>{<br> options.AddDefaultPolicy(policy =><br> policy.WithOrigins("https://shop.example.com")<br> .AllowAnyHeader()<br> .AllowAnyMethod());<br>});<br><br>var app = builder.Build();<br><br>app.UseCors();<br><br>app.MapPost("/success", ([FromForm] OrderId id, IOrderService order)<br> => order.Handle(id));<br><br>app.Run();

Vi du nay cho thay cach cap nhat ung dung Minimal API. Tuy nhien, neu ung dung dung MVC hoac Razor Pages, ban co the bat ngo vi token cu van duoc tao va kiem tra.

Vi sao token van xuat hien va request van bi loi 400?

Blazor static server-side rendering da duoc cap nhat de khong con tao hoac kiem tra anti-CSRF token trong cac truong hop su dung mac dinh CsrfProtectionMiddleware. Tuy nhien, MVC va Razor Pages van tao va kiem tra token. Vi vay, endpoint van that bai neu token bi thay doi hoac khong ton tai trong form gui len.

Co the xem day la co che defence in depth, tuc nhieu lop bao ve cung ton tai. Tuy nhien, neu co che moi da tot hon, viec MVC va Razor Pages tiep tuc phu thuoc vao token tao ra mot trai nghiem chua that su nhat quan.

De thu nghiem, co the tim cach tat hoan toan viec tao va kiem tra token trong MVC va Razor Pages. Day khong phai cach lam duoc khuyen nghi cho production; ma duoi day chi la vi du mang tinh PoC va can duoc kiem tra bao mat that ky.

Tat viec tu dong them token vao form

Cach don gian la dung ITagHelperInitializer de tat antiforgery cho moi FormTagHelper:

public class DisableAntiForgeryTagHelperInitializer<br> : ITagHelperInitializer<FormTagHelper><br>{<br> public void Initialize(FormTagHelper helper, ViewContext context)<br> {<br> helper.Antiforgery = false;<br> }<br>}

Dang ky initializer trong DI container:

builder.Services.AddSingleton<ITagHelperInitializer<FormTagHelper>>(<br> new DisableAntiForgeryTagHelperInitializer());

Cach nay ngan viec tao token. Tuy nhien, neu khong tat ca viec kiem tra, moi request doc form data se co the that bai.

Go bo filter kiem tra token mac dinh

MVC va Razor Pages tu dong them AutoValidateAntiforgeryTokenAttribute vao page va action. Can tao convention de go bo filter nay:

public class RemoveAntiforgeryConvention<br> : IPageApplicationModelConvention, IControllerModelConvention<br>{<br> public void Apply(PageApplicationModel model)<br> => RemoveFilter(model.Filters);<br><br> public void Apply(ControllerModel controller)<br> => RemoveFilter(controller.Filters);<br><br> private static void RemoveFilter(IList<IFilterMetadata> filters)<br> {<br> var antiforgeryFilter = filters.FirstOrDefault(<br> f => f is AutoValidateAntiforgeryTokenAttribute);<br><br> if (antiforgeryFilter != null)<br> {<br> filters.Remove(antiforgeryFilter);<br> }<br> }<br>}

Dang convention vao cau hinh:

builder.Services.AddRazorPages(options =><br>{<br> options.Conventions.Add(new RemoveAntiforgeryConvention());<br>});<br><br>builder.Services.AddControllersWithViews(options =><br>{<br> options.Conventions.Add(new RemoveAntiforgeryConvention());<br> options.Filters.Add<CsrfProtectionAuthorizationFilter>();<br>});

Xu ly IAntiforgeryValidationFeature

Cac buoc tren van chua du. FormFeature co phuong thuc HandleUncheckedAntiforgeryValidationFeature, duoc chay truoc khi ung dung truy cap Request.Form. Phuong thuc nay kiem tra xem AntiforgeryMiddleware hoac CsrfProtectionMiddleware co them mot IAntiforgeryValidationFeature dang chan vao request hay khong.

Neu co, viec doc form se nem exception va cuoi cung co the tao ra loi 500 Internal Server Error, vi framework cho rang mot thanh phan nao do phai xu ly viec validation.

Do do, can them mot filter tuong tu AutoValidateAntiforgeryTokenAttribute, nhung filter nay kiem tra IAntiforgeryValidationFeature thay vi kiem tra token:

internal sealed partial class CsrfProtectionAuthorizationFilter<br> : IAuthorizationFilter, IAntiforgeryPolicy<br>{<br> private readonly ILogger _logger;<br><br> public CsrfProtectionAuthorizationFilter(ILoggerFactory loggerFactory)<br> {<br> _logger = loggerFactory.CreateLogger(GetType());<br> }<br><br> public void OnAuthorization(AuthorizationFilterContext context)<br> {<br> ArgumentNullException.ThrowIfNull(context);<br><br> if (!context.IsEffectivePolicy<IAntiforgeryPolicy>(this))<br> {<br> Log.NotMostEffectiveFilter(_logger,<br> typeof(IAntiforgeryPolicy));<br> return;<br> }<br><br> if (context.HttpContext.Features<br> .Get<IAntiforgeryValidationFeature>() is { IsValid: false })<br> {<br> Log.AntiforgeryTokenInvalid(_logger);<br> context.Result = new AntiforgeryValidationFailedResult();<br> }<br> }<br><br> private static partial class Log<br> {<br> [LoggerMessage(1, LogLevel.Information,<br> "Antiforgery token validation failed.",<br> EventName = "AntiforgeryTokenInvalid")]<br> public static partial void AntiforgeryTokenInvalid(ILogger logger);<br><br> [LoggerMessage(2, LogLevel.Trace,<br> "Skipping the execution of current filter as its not the most effective filter implementing the policy {FilterPolicy}.",<br> EventName = "NotMostEffectiveFilter")]<br> public static partial void NotMostEffectiveFilter(<br> ILogger logger, Type filterPolicy);<br> }<br>}

Day chi la mot PoC duoc lap nhanh de minh hoa cac thanh phan can thiet. Chua co bao dam rang no hoat dong dung trong moi truong hop va khong tao ra lo hong bao mat. Neu ap dung y tuong nay, can kiem thu ky va danh gia bao mat truoc khi dua vao su dung.

Ket luan

.NET 11 Preview 6 them thuat toan bao ve CSRF moi cho ASP.NET Core, dua tren Fetch Metadata HTTP header. Cac header nay da duoc trinh duyet gui trong cac request tu nam 2023, cung cap cho framework mot cach nhe hon de nhan dien va chan request cross-site thay vi phu thuoc hoan toan vao synchronizer token.

Co che token cu van co nhieu uu diem va da hoat dong hieu qua trong nhieu nam, nhung cung co mot so han che: phu thuoc vao Data Protection API, can chia se key trong moi truong nhieu instance, gay bat tien khi nguoi dung mo nhieu tab va phat sinh chi phi xu ly trong moi request.

Co che moi cho phep Blazor SSR va Minimal API su dung Fetch Metadata middleware. Ban co the xoa cac lenh goi UseAntiforgery() neu muon opt-in vao hanh vi moi. Khi can cho phep request cross-origin, hay tat CSRF cho endpoint phu hop hoac them origin cu the vao CORS policy.

MVC va Razor Pages hien van tiep tuc tao va kiem tra token cu. Co the can thiep de loai bo token pattern va chi dua vao co che moi, nhung cach lam nay doi hoi nhieu hack va chua phai huong duoc khuyen nghi. Hay coi day la mot diem khoi dau cho viec nghien cuu, khong phai cau hinh san sang cho production.

Luu y: Bao mat CSRF phu thuoc vao cach ung dung xu ly cookie, form, authentication, CORS va endpoint. Moi thay doi doi voi co che antiforgery can duoc kiem thu trong cac tinh huong tan cong thuc te truoc khi trien khai.