Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tarafından Fiyaz Hasan ve Rick Anderson
Siteler arası istek sahteciliği, kötü amaçlı bir web uygulamasının bir istemci tarayıcı ile bu tarayıcıya güvenen bir web uygulaması arasındaki etkileşimi etkilediği, web'de barındırılan uygulamalara yönelik bir saldırıdır. Bu saldırılar mümkündür çünkü web tarayıcıları bir web sitesine her istekle birlikte bazı kimlik doğrulama belirteçleri türlerini otomatik olarak gönderir. Saldırı, kullanıcının daha önce kimliği doğrulanmış oturumundan yararlandığından, bu açıklardan yararlanma biçimi tek tıklamayla saldırı veya oturum sürme olarak da bilinir. Siteler arası istek sahteciliği, XSRF veya CSRF olarak da bilinir.
CSRF saldırısı örneği:
Bir kullanıcı form kimlik doğrulamasını kullanarak
www.good-banking-site.example.comsitesine oturum açar. Sunucu kullanıcının kimliğini doğrular ve kimlik doğrulaması cookieiçeren bir yanıt gönderir. Site, geçerli bir kimlik doğrulaması cookieile aldığı tüm isteklere güvendiği için saldırıya açık durumdadır.Kullanıcı kötü amaçlı bir siteyi ziyaret etti.
www.bad-crook-site.example.comKötü amaçlı site,
www.bad-crook-site.example.comaşağıdaki örneğe benzer bir HTML formu içerir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.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>Formun
actionkötü amaçlı siteye değil, güvenlik açığı bulunan siteye gönderildiğini fark edin. Bu, CSRF'nin "siteler arası" bölümüdür.Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı cookie için kimlik doğrulamasını
www.good-banking-site.example.comotomatik olarak içerir.İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır
www.good-banking-site.example.comve kimliği doğrulanmış bir kullanıcının gerçekleştirmesine izin verilen tüm eylemleri gerçekleştirebilir.
Kullanıcının formu göndermek için düğmeyi seçtiği senaryoya ek olarak, kötü amaçlı site şunları yapabilir:
- Formu otomatik olarak gönderen bir betik çalıştırın.
- Form gönderimini AJAX isteği olarak gönderin.
- CSS kullanarak formu gizleyin.
Bu alternatif senaryolar, başlangıçta kötü amaçlı siteyi ziyaret etmekten başka kullanıcıdan herhangi bir eylem veya giriş gerektirmez.
HTTPS kullanmak CSRF saldırısını engellemez. Kötü amaçlı site, güvenli olmayan bir istek gönderebildiği kadar kolay bir şekilde https://www.good-banking-site.example.com/ isteği de gönderebilir.
Bazı saldırılar GET isteklerine yanıt veren uç noktaları hedefler ve bu durumda eylemi gerçekleştirmek için bir görüntü etiketi kullanılabilir. Bu saldırı biçimi, görüntülere izin veren ancak JavaScript'i engelleyen forum sitelerinde yaygındır. Değişkenlerin veya kaynakların değiştirildiği GET isteklerinde durumu değiştiren uygulamalar kötü amaçlı saldırılara karşı savunmasızdır. Durumu değiştiren GET istekleri güvenli değildir. Get isteğinde hiçbir zaman durumu değiştirmemek en iyi yöntemdir.
Kimlik doğrulaması için tanımlama bilgileri kullanan web uygulamalarına CSRF saldırıları mümkündür çünkü:
- Tarayıcılar, web uygulaması tarafından verilen çerezleri depolar.
- Depolanan tanımlama bilgileri, kimliği doğrulanmış kullanıcılar için oturum tanımlama bilgilerini içerir.
- Tarayıcılar, bir etki alanıyla ilişkili tüm tanımlama bilgilerini, uygulama isteğinin tarayıcıda nasıl oluşturulduğundan bağımsız olarak her istekte web uygulamasına gönderir.
Ancak CSRF saldırıları, tanımlama bilgilerini kötüye kullanmakla sınırlı değildir. Örneğin, Temel ve Özet kimlik doğrulaması da savunmasızdır. Kullanıcı Temel veya Özet kimlik doğrulamasıyla oturum açtığında, oturum bitene kadar tarayıcı kimlik bilgilerini otomatik olarak gönderir.
Bu bağlamda oturum, kullanıcının kimliğinin doğrulandığı istemci tarafı oturumuna başvurur. Sunucu tarafı oturumlarıyla veya ASP.NET Core oturum ara yazılımıyla ilgisizdir.
Kullanıcılar, önlemler alarak CSRF güvenlik açıklarına karşı koruma sağlayabilir:
- Web uygulamalarını kullanmayı bitirdiğinizde oturumunu kapatın.
- Tarayıcı tanımlama bilgilerini düzenli aralıklarla temizleyin.
Ancak CSRF güvenlik açıkları, son kullanıcıyla değil, temel olarak web uygulamasıyla ilgili bir sorundur.
Kimlik doğrulamasının temelleri
Cookietabanlı kimlik doğrulaması, popüler bir kimlik doğrulaması biçimidir. Özellikle Tek Sayfalı Uygulamalar (SPA' lar) için belirteç tabanlı kimlik doğrulama sistemlerinin popülerliği artmaktadır.
Cookietabanlı kimlik doğrulaması
Bir kişi kullanıcı adı ve parolasını kullanarak kimlik doğrulaması yaptığında, kendisine kimlik doğrulama bileti içeren bir belirteç verilir. Belirteç, kimlik doğrulaması ve yetkilendirme için kullanılabilir. Belirteç, istemcinin yaptığı her istekle gönderilen bir cookie olarak depolanır. Bu cookie’ın oluşturulması ve doğrulanması, cookie kimlik doğrulama ara yazılımı kullanılarak gerçekleştirilir. Arayazılım, bir kullanıcı kimliğini şifrelenmiş bir olarak seri hale getirmektedir. Sonraki isteklerde ara yazılım cookie'yi doğrular, kimliği yeniden oluşturur ve kimliği HttpContext.User özelliğine atar.
Belirteç tabanlı kimlik doğrulaması
Bir kullanıcının kimliği doğrulandığında, ona bir belirteç verilir (bir sahteciliğe karşı koruma belirteci değil). Belirteç, haklar biçiminde kullanıcı bilgilerini veya uygulamada tutulan kullanıcı durumuna işaret eden bir referans belirteci içerir. Kullanıcı kimlik doğrulaması gerektiren bir kaynağa erişmeye çalıştığında belirteç, Taşıyıcı belirteci biçiminde ek yetkilendirme üst bilgisi ile uygulamaya gönderilir. Bu yaklaşım uygulamayı durumsuz hale getirir. Sonraki her istekte, belirteç sunucu tarafı doğrulama isteğine geçirilir. Bu belirteç şifrelenmez; kodlanır. Sunucuda belirtecin kodu bilgilerine erişmek için çözülmektedir. Sonraki isteklerde belirteci göndermek için belirteci tarayıcının yerel depolama alanında depolayın. Jetonu tarayıcı yerel depolama alanına yerleştirmek, geri almak ve taşıyıcı jeton olarak kullanmak, CSRF saldırılarına karşı koruma sağlar. Ancak, uygulama XSS aracılığıyla betik eklemeye veya güvenliği aşılmış bir dış JavaScript dosyasına karşı savunmasız olursa, bir siber saldırı yerel depolama alanından herhangi bir değeri alabilir ve kendilerine gönderebilir. ASP.NET Core varsayılan olarak değişkenlerden gelen tüm sunucu tarafı çıkışlarını kodlayarak XSS riskini azaltır. Html.Raw veya özel kodu güvenilmeyen girişle kullanarak bu davranışı geçersiz kılarsanız XSS riskini artırabilirsiniz.
Belirteç tarayıcının yerel depolama alanında depolanıyorsa CSRF güvenlik açığı konusunda endişelenmeyin. CSRF, belirtecin bir cookie içinde depolandığı durumlarda sorundur. Daha fazla bilgi için GitHub konusuna bakın: SPA kodu örneği iki çerez ekler.
Bir alan adında barındırılan birden fazla uygulama
Paylaşılan barındırma ortamları oturum ele geçirme, oturum açma CSRF ve diğer saldırılara karşı savunmasızdır.
ve example1.contoso.net farklı konaklar olsa example2.contoso.net da, etki alanı altındaki *.contoso.net konaklar arasında örtük bir güven ilişkisi vardır. Bu örtük güven ilişkisi, potansiyel olarak güvenilmeyen konakların birbirlerinin çerezlerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP çerezleri için geçerli olmayabilir).
Aynı etki alanında barındırılan uygulamalar arasındaki güvenilir tanımlama bilgilerini istismar eden saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her bir uygulama kendi alanında barındırıldığında, istismar edilecek örtük bir güven ilişkisi yoktur.
Meta veri başlıklarını alma
Modern tarayıcılar, her isteğe Fetch Metadata isteği üst bilgileri (en önemlisi Sec-Fetch-Site) ekler.
Sec-Fetch-Site isteği başlatan kaynak ile istenen kaynak arasındaki ilişkiyi açıklar: same-origin sitenin kendisine yaptığı bir isteği tanımlarken same-site ve cross-site başka bir kaynak tarafından başlatılan istekleri tanımlar.
Origin üst bilgisi, başlatan origin'i taşır ve Fetch Metadata'dan önceki tarayıcılar için bir geri dönüş mekanizması olarak işlev görür.
Sec-Fetch-Site ve Originyasak istek üst bilgileridir: tarayıcı bunları ayarlar ve bir sayfada çalışan JavaScript bunları geçersiz kılamaz veya oluşturamaz. Bu da onları, sunucu tarafından verilmiş bir belirteç olmadan, bir sitenin kendi isteklerini siteler arası isteklerden ayırt etmek için güvenilir bir gösterge hâline getirir. ASP.NET Core yerleşik otomatik CSRF koruması, açıkça güvenilmeyen siteler arası form gönderilerini reddetmek için bu sinyali kullanır.
ASP.NET Core'de otomatik CSRF koruması
ASP.NET Core, WebApplication.CreateBuilder ile oluşturulan uygulamalarda varsayılan olarak etkin olan otomatik bir CSRF koruma ara yazılımıyla birlikte gelir.
Belirteç tabanlı kötü amaçlı yazılımdan koruma sisteminden farklı olarak, bu ara yazılım belirteçleri düzenlemez veya doğrulamaz. Bunun yerine, Sec-Fetch-Site ve OriginFetch meta veri başlıklarını inceler ve istek için bir doğrulama kararı kaydeder. Gönderilen form verilerini işleyen bileşenler bu kararı zorunlu kılır ve açıkça güvenilmeyen çıkış noktaları arası form gönderilerini reddeder.
Çoğu uygulama için kod değişikliği gerekmez: aynı kaynak tarayıcı istekleri, güvenli HTTP yöntemleri ve tarayıcı dışı istemciler (curlsunucudan sunucuya, mobil uygulamalar) etkilenmeden geçer. Ara yazılım öncelikli olarak tarayıcıdan çıkış noktaları arası form gönderilerini kabul eden uygulamaları etkiler. Örneğin, formu farklı bir kaynakta bulunan bir API'ye postalayan bir site. Bu senaryoların CORS'yi güvenilir kaynağı bildirecek şekilde yapılandırmaları veya uç noktayı devre dışı bırakmaları gerekir.
Bu ara yazılım, belirteç tabanlı sahteciliğe karşı koruma sistemine ek olarak çalışır. İki koruma birlikte bulunur ve ikisi de aynı uç noktada etkin olabilir. Her birinin ne zaman uygulanacağıyla ilgili bir karşılaştırma için bkz. Belirteç tabanlı kötü amaçlı yazılım önleme ile etkileşim.
Nasıl çalışır?
Ara yazılım, her istek için bir karara ulaşmak için izin verilen veya reddedilen kısa bir kural zincirini değerlendirir. Denetimler sırayla çalıştırılır ve ilk eşleşme kazanır:
-
Güvenli HTTP yöntemlerine her zaman izin verilir.
GET,HEAD,OPTIONSveTRACEistekleri geçer. Bu, RFC 9110 §9.2.1'e dayanmaktadır ve uç noktalarınGETsırasında durum değiştirmemesi gerektiğine ilişkin öteden beri süregelen kuralla tutarlıdır. -
Sec-Fetch-Site: same-originveyaSec-Fetch-Site: noneizin verilir. Modern tarayıcılar her istekteSec-Fetch-Sitegönderir.same-originnormal uygulama içi gezintiyi ve getirmeyi kapsar venonedoğrudan kullanıcı tarafından başlatılan istekleri kapsar (yer işareti kullanarak URL yazma). Bu en yaygın kod yoludur; en meşru tarayıcı trafiği buradan çıkar. - CORS'tan güvenilir bir kaynağa izin verilir. İstek bir
Originüst bilgisi taşıyorsa ve uç nokta için çözümlenen CORS ilkesi bu kaynağa güveniyorsa, isteğe izin verilir. Ara yazılım, ilkeyi CORS ara yazılımının yaptığı gibi belirler: önce[EnableCors("name")]öğesindeki uç nokta başına ilke, ardındanAddDefaultPolicyile kaydedilen varsayılan ilke. Bu kurala ilişkin önemli sınırlamalar için Bkz. Kaynaklar arası istemcilere izin verme. - Diğer
Sec-Fetch-Sitetüm değerler reddedilir.Sec-Fetch-Site,cross-siteveyasame-siteolduğunda ve kaynağa CORS aracılığıyla güvenilmiyorsa, istek reddedilir. -
Sec-Fetch-Siteyok, ancakOriginmevcut: ara yazılım,Originöğesini istekten oluşturulanscheme://host[:port]ile karşılaştırır. Eşleşiyorsa isteğe izin verilir; aksi takdirde reddedilir. Bu, Fetch Metadata belirtiminden (~2020'de yayımlandı) daha eski tarayıcılar için geri dönüş yoludur. - Hayır
Sec-Fetch-Siteve hayırOrigin: isteğe izin verilir. Tarayıcılar bir yazma isteğinde bunlardan her zaman en az birini gönderir; bu nedenle ikisinin de bulunmadığı bir istek, neredeyse kesin olarakcurl, Postman, bir mobil uygulama veya sunucudan sunucuya çağrı yapan bir istemci gibi tarayıcı dışı bir istemciden geliyordur. CSRF yalnızca tarayıcıya yönelik bir saldırı vektördür, bu nedenle bu istekler geçer.
Ara katman yazılımı, isteği bizzat sonlandırmak yerine bu kararı istek üzerinde kaydeder. Reddedilen bir kararın HTTP 400 Bad Request yanıtına nasıl ve ne zaman dönüştüğü için bkz. Ertelenen doğrulama.
Ertelenen doğrulama
Ara yazılım bir isteği kendi başına reddetmez. Bunun yerine, isteğin IAntiforgeryValidationFeature özelliğine ilişkin kararını kaydeder; belirteç tabanlı sahteciliğe karşı koruma sisteminin kullandığı özellik de budur ve ret kararı geçersiz olarak kaydedilir. İstek, işlem hattında ilerlemeye devam eder. Geçersiz bir karar, yalnızca form verilerini işleyen bir bileşen bunu gözlemlediğinde HTTP 400 Bad Request olur. Bu erteleme, belirteç tabanlı sistemin zaten nasıl davrandığıyla eşleşir: karar erken oluşturulur ancak formun kullanıldığı noktada uygulanır.
Aşağıdaki bileşenler IAntiforgeryValidationFeature değerini okur ve kaydedilen karar geçersiz olduğunda bir isteği 400 - Bad Request ile reddeder:
- Antiforgery tarafından korunan MVC eylemleri.
- Form parametresini bağlayan Minimal API uç noktaları.
- Blazor SSR uç noktaları.
- İstek formunu doğrudan okuyan ve arka uç işlevi gören tüm kodlar.
Her tüketici, sonuca güvenmeden önce sahteciliğe karşı koruma veya CSRF ara yazılımının gerçekten çalıştığını doğrular; bu nedenle, bu ara yazılımlardan hiçbirini içermeyen bir işlem hattı yanlış reddetmelere yol açmaz.
Bu modelin bir sonucu, form verilerini hiç okumayan bir uç noktanın, karar geçersiz olduğunda bile çalıştırılmasıdır. Örneğin, istek gövdesini JSON'dan bağlayan bir JSON API uç noktası veya istek gövdesini yok sayan bir işleyici, kaynaklar arası bir istekte otomatik olarak reddedilmez. Karar, onu incelemek isteyen kodun erişebilmesi için IAntiforgeryValidationFeature üzerinde yine de kayıtlı tutulur, ancak bunu zorlayan hiçbir şey yoktur. CSRF, form tabanlı bir cookie saldırı vektörüdür; bu nedenle, tarayıcı tarafından gönderilen bir formu işlemeyen uç noktaların genellikle bu tür bir reddetmeye ihtiyacı yoktur. SayfalarıRazor , MVC görünümlerini Blazor , SSR'yi ve Minimal API form bağlamasını işleyen uç noktalar, korumayı otomatik olarak alır.
Varsayılan davranış
Ara yazılım tarafından WebApplication.CreateBuilder otomatik olarak kaydedilir ve kimlik doğrulaması ve yetkilendirmeden sonra çalışır. Her isteği kayıtlı ICsrfProtection uygulamayı kullanarak doğrular ve varsayılan olarak Nasıl çalışır? başlığında açıklanan kuralları uygular. Varsayılan uygulama değiştirilebilir; bkz . Özelleştirme: uygulama ICsrfProtection. Ara yazılımı tamamen kapatmak için bkz. Genel olarak devre dışı bırakma.
Sonuç olarak, aşağıdaki gibi bir form işleme uç noktasına sahip minimal bir uygulama halihazırda korunmaktadır:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapPost("/widgets", ([FromForm] Widget w) =>
Results.Created($"/widgets/{w.Id}", w));
app.Run();
Aynı kaynak POST /widgets isteğinde bulunan bir tarayıcı uç noktaya normal şekilde ulaşır.
https://attacker.example.com adresindeki, aynı formu gönderen bir tarayıcı, uç nokta formu bağladığında, işleyici gövdesi çalışmadan önce 400 - Bad Request ile reddedilir.
curl veya Sec-Fetch-Site olmadan yapılan bir Origin isteğine izin verilir.
Reddedilme formu işleyen bileşenlere ertelendiği için, form verilerini okumayan bir uç nokta — örneğin gövdesini JSON'dan bağlayan bir JSON API'si — kaynaklar arası bir istekte bile otomatik olarak reddedilmez. Karar, incelemek isteyen kod isteğinde yine de kaydedilir.
Ara yazılım mevcut kötü amaçlı yazılımdan koruma modeliyle tümleşir:
-
Minimal API'ler: Bir uç noktada
.DisableAntiforgery()çağrılması, bu uç noktayı hem belirteç tabanlı ara yazılımın hem de CSRF koruma ara yazılımının dışında tutar. Aynı meta veriler (IAntiforgeryMetadata { RequiresValidation = false }) her ikisi tarafından da denetlendi. -
MVC denetleyicileri ve eylemleri:
[IgnoreAntiforgeryToken]ayrıca uç noktayı her iki korumadan da çıkarır.
Farklı kaynaklardan gelen istemcilere izin verme
İşlem yapılmasını gerektiren en yaygın senaryo, farklı bir kaynağa form gönderen tarayıcı tabanlı bir istemcidir; örneğin, https://app.contoso.com adresindeki bir sitenin https://api.contoso.com adresindeki bir API'ye form göndermesi. Bu tür form gönderileri, Sec-Fetch-Site öğesi same-site yerine cross-site veya same-origin olduğundan varsayılan olarak reddedilir ve form işleyicisi bu kararı bir 400 - Bad Request ile uygular.
CSRF ara yazılımı kendi güven listesini sunmaz. Uç nokta için CORS ara yazılımının çözdüğü aynı CORS ilkesini yeniden kullanır: Bu ilke isteğin Origin öğesine izin veriyorsa, CSRF ara yazılımı istek için izin verildiği yönünde bir karar kaydeder.
İlke, uç nokta başına şu sırayla seçilir:
-
[EnableCors("api")](MVC) veya.RequireCors("api")(Minimal API) → adlandırılmış ilke"api". - Uç noktada CORS meta verisi yok →
AddDefaultPolicyile kaydedilen varsayılan ilke. - Eşleşen ilke yok (adlandırılmış ilke kaydedilmemiş, varsayılan ilke yok veya
services.AddCors()hiç çağrılmadı) → CORS’tan türetilen güven yok. Ara katman yazılımı,Sec-Fetch-Siteve Origin-vs-Host kurallarına başvurur.
Varsayılan ilke ve Minimum API uç noktası kullanan en küçük örnek:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
policy.WithOrigins("https://app.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod());
});
var app = builder.Build();
app.UseCors();
app.MapPost("/widgets", ([FromForm] Widget w) =>
Results.Created($"/widgets/{w.Id}", w));
app.Run();
Tek bir uç noktadaki adlandırılmış ilke için:
app.MapPost("/widgets", ([FromForm] Widget w) => Results.Created($"/widgets/{w.Id}", w))
.RequireCors("api");
Uyarı
AllowAnyOrigin kasıtlı olarak CSRF güven sinyali olarak kabul edilmez .
AllowAnyOrigin, "herhangi bir tarayıcı bu kaynağı okuyabilir" anlamına gelir; bu, "herhangi bir kökenin kullanıcı adına durumu değiştirebileceği" meselesinden farklıdır. AllowAnyOrigin’e güvenilir muamelesi yapmak, bu ara yazılımı kökenler arası yazma işlemleri açısından etkisiz hâle getirir. CSRF korumalı yazma işlemleriyle birlikte herkese açık okuma CORS ilkesine ihtiyaç duyan uygulamalar, güvenilir yazma kaynaklarını açıkça WithOrigins listelemeli veya cookie tabanlı kimlik doğrulamaya dayanmıyorlarsa yazma uç noktalarını hariç tutmayı tercih etmelidir.
[DisableCors] ifadesinin bir uç noktada kullanılması, CSRF’den muafiyet anlamına gelmez. Bu, CORS’tan türetilen güven adımını atlar; ancak isteğin yine de Sec-Fetch-Site ve Origin-vs-Host kurallarını karşılaması gerekir. CSRF koruması dışında bırakmak için bkz. Bir uç noktayı kapsam dışında bırakma.
CORS’un kendisini —AddCors, AddDefaultPolicy, AddPolicy, WithOrigins ve ilke oluşturucu API’sinin geri kalanı— yapılandırmaya ilişkin ayrıntılar için ASP.NET Core’da Kaynaklar Arası İstekleri (CORS) Etkinleştirme konusuna bakın.
Bir uç noktayı devre dışı bırakma
Uç nokta tarayıcıya erişilemiyorsa veya taşıyıcı belirteci veya API anahtarı gibi mekanizma olmayancookie bir sistem tarafından güvenli hale getiriliyorsa, ara yazılımı genel olarak devre dışı bırakmak yerine tek tek devre dışı bırakabilirsiniz.
Minimal API'ler — uç noktada veya grupta DisableAntiforgery çağrısı yapın:
app.MapPost("/api/webhook", (WebhookPayload p) => Results.Accepted())
.DisableAntiforgery();
MVC denetleyicileri — [IgnoreAntiforgeryToken] özniteliğini eyleme veya denetleyiciye uygulayın:
[ApiController]
[Route("api/[controller]")]
[IgnoreAntiforgeryToken]
public class WebhookController : ControllerBase
{
[HttpPost]
public IActionResult Post([FromBody] WebhookPayload payload) => Accepted();
}
Her iki yaklaşım da uç noktaya IAntiforgeryMetadata { RequiresValidation = false } ekler; CSRF ara yazılımı da bunu dikkate alarak doğrulamayı atlar.
Uyarı
Bir uç noktada CSRF korumasını devre dışı bırakmak, yalnızca uç nokta CSRF saldırılarına karşı savunmasız olmadığında (örneğin, bir tarayıcıdan çağrılamayan veya taşıyıcı belirteçler veya API anahtarları gibi kimlik doğrulaması olmayanlarlacookie güvenliği sağlanan uç noktalar) yapılmalıdır. Kimlik doğrulaması için çerezlere dayanan tarayıcıdan erişilebilen uç noktalarda CSRF korumasını devre dışı bırakmayın.
Genel olarak devre dışı bırakma
Ara yazılım, yapılandırma anahtarı kullanılarak uygulamanın tamamında DisableCsrfProtection devre dışı bırakılabilir. Bu, istisnai durumlar için bir çözümdür; tercih edilmesi gereken, uç nokta başına hariç tutma seçenekleridir.
appsettings.json'da:
{
"DisableCsrfProtection": true
}
Veya ortam değişkeni olarak:
ASPNETCORE_DisableCsrfProtection=true
Bu anahtar olarak trueayarlandığında, WebApplication ara yazılımı işlem hattına kaydetmeyi atlar.
ICsrfProtection hizmeti kayıtlı kalmaya devam eder, bu nedenle onu doğrudan çözümleyen her şey çalışmaya devam eder.
Uyarı
Otomatik CSRF ara yazılımı, bir uygulama çağrısı app.UseAntiforgery()yapmasa bile doğrulama gerektiren uç noktalar için kötü amaçlı yazılımdan koruma gereksinimini de karşılar. Bir uygulama sahteciliğe karşı korumaya dayanıyor ancak app.UseAntiforgery() çağrısını yapmıyorsa, CSRF ara yazılımını genel olarak devre dışı bırakmak veya ara yazılımın eklenmediği, WebApplication ile oluşturulmamış bir ana bilgisayarda çalıştırmak, bu uç noktaları sahteciliğe karşı koruma ara yazılımı olmadan bırakır. Böyle bir uç noktaya yapılan bir istek, bu durumda bir istisna fırlatır. Bu yapılandırmada app.UseAntiforgery() çağırın.
Tarayıcı desteği
Sec-Fetch-Site Chromium tabanlı tarayıcıların, Firefox'un ve Safari'nin tüm güncel sürümleri tarafından desteklenir. Güvenilir bir uyumluluk tablosu için Sec-Fetch-Site MDN başvuru sayfasına bakın.
Fetch Metadata'dan daha eski olan tarayıcılar Sec-Fetch-Site göndermez. Bu istemciler için ara yazılım, Origin üst bilgisini isteğin protokolü ve ana bilgisayar adıyla karşılaştırma yoluna başvurur. Tarayıcılar uzun yıllardır kaynaklar arası yazma isteklerinde Origin gönderiyor, bu nedenle bu yedek çözüm eski tarayıcılardan gelen trafiğin neredeyse tamamını kapsıyor.
Tarayıcı dışı istemciler — curl, Postman, mobil uygulamalar, sunucudan sunucuya çağrı yapanlar — genellikle ne Sec-Fetch-Site ne de Origin gönderir. CSRF, tarayıcının tanımlama bilgileri gibi ortam kimlik bilgilerini otomatik olarak eklemesine bağlı olan yalnızca tarayıcıya yönelik bir saldırı vektör olduğundan bu isteklere izin verilir. API'ye saldırmak isteyen tarayıcı dışı bir istemcinin CSRF'ye ihtiyacı yoktur; API'yi sahip olduğu kimlik bilgileriyle doğrudan çağırabilir.
Özelleştirme: uygulama ICsrfProtection
Karar mantığı tek yöntemli bir arabirimin arkasında yer alır:
namespace Microsoft.AspNetCore.Antiforgery;
public interface ICsrfProtection
{
ValueTask<CsrfProtectionResult> ValidateAsync(HttpContext context);
}
Varsayılan uygulamayı değiştirmek için DI'ye bir singleton kaydedin. Çerçeve TryAddSingleton kullandığı için, açık bir AddSingleton çağrısı varsayılanı geçersiz kılar:
builder.Services.AddSingleton<ICsrfProtection, AllowlistCsrfProtection>();
Güven modeli CORS'ye uymadığında (örneğin, iş ortağı kaynaklarından oluşan sabit bir izin verilenler listesi tercih edildiğinde veya daha katı kurallar gerektiğinde) özel bir uygulama kullanışlıdır:
using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Http;
public sealed class AllowlistCsrfProtection : ICsrfProtection
{
private static readonly HashSet<string> SafeMethods =
new(StringComparer.OrdinalIgnoreCase) { "GET", "HEAD", "OPTIONS", "TRACE" };
private static readonly HashSet<string> TrustedOrigins =
new(StringComparer.OrdinalIgnoreCase)
{
"https://app.contoso.com",
"https://admin.contoso.com",
};
public ValueTask<CsrfProtectionResult> ValidateAsync(HttpContext context)
{
if (SafeMethods.Contains(context.Request.Method))
{
return ValueTask.FromResult(CsrfProtectionResult.Allowed());
}
var origin = context.Request.Headers.Origin.ToString();
var allowed = !string.IsNullOrEmpty(origin) && TrustedOrigins.Contains(origin);
return ValueTask.FromResult(
allowed ? CsrfProtectionResult.Allowed() : CsrfProtectionResult.Denied());
}
}
Ara yazılım, hangi gerçekleme kayıtlı olursa olsun .DisableAntiforgery() / [IgnoreAntiforgeryToken] için geçerliliği hâlâ korur; devre dışı bırakma işlemi, ValidateAsync çağrılmadan önce doğrudan ara yazılımın kendisi tarafından ele alınır.
Belirteç tabanlı sahteciliği önleme ile etkileşim
İki CSRF savunması farklı katmanları hedefler ve birlikte var olacak şekilde tasarlanmıştır. Ayrıca aynı istek mekanizmasını da paylaşırlar: her ikisi de sonuçlarını IAntiforgeryValidationFeature üzerine kaydeder ve form tüketicileri orada bulunan kararı uygular.
| Aspect | Token tabanlı AntiforgeryMiddleware |
Otomatik CSRF koruması ara yazılımı |
|---|---|---|
| Tanıtıldı | ASP.NET Core 2.0+ | .NET 11 |
| Activation |
app.UseAntiforgery() aracılığıyla izin verme (veya AddMvc / MapRazorPages / AddRazorComponents yoluyla örtük olarak) |
WebApplication.CreateBuilder tarafından otomatik olarak eklenen |
| Doğrulama | Senkronize belirteç (form alanı + cookie çifti) |
Sec-Fetch-Site
/
Origin Üstbilgi |
| Requires | belirteç şifrelemesi için ASP.NET Core Veri Korumasına Genel Bakış | Token yok, durum yok |
| Tarayıcı kapsamı | Tanımlama bilgileri gönderen tüm tarayıcılar | Tüm modern tarayıcılar; eski sistemler için Origin geri dönüş seçeneği |
| Uç nokta bazında devre dışı bırakma | .DisableAntiforgery() / [IgnoreAntiforgeryToken] |
Aynı — her ikisi de aynı meta verileri esas alır |
Belirteç tabanlı ara yazılım, özellikle kötü amaçlı bir sitenin kullanıcının ortam tanımlama bilgilerini kullanarak savunmasız bir siteye form POST tetiklediği klasik CSRF saldırı düzenine karşı koruma sağlar. Otomatik CSRF ara yazılımı, tarayıcı tarafından sağlanan meta verileri kullanarak HTTP katmanında aynı tehdidi giderir. Her ikisi de aynı uç noktada etkin olabilir ve birçok uygulama derinlemesine savunmadan yararlanacaktır:
- Belirteç sistemini zaten kullanan sayfalar, MVC ve Razor SSR uygulamaları, belirteç akışını değiştirmeden belirteç doğrulamadan önce çalışan üst bilgi tabanlı bir denetim elde eder.Blazor
- Form bağlayan Minimal API uygulamaları,
app.UseAntiforgery()çağrısı yapmaya veyaIAntiforgeryöğesini uç noktalardan geçirmeye gerek kalmadan yararlı bir varsayılan davranış elde eder. - Farklı origin’lerden çağrılan SPA’lardaki API’ler, bir CORS izin listesiyle birlikte bu ara katman yazılımına dayanabilir ve API hiçbir zaman HTML formu sunmuyorsa token sistemini tamamen atlayabilir.
Otomatik CSRF ara yazılımı, birçok senaryoda belirteç tabanlı sistemin yerini alır çünkü her ikisi de aynı form işleme uç noktalarını korur. Belirteç tabanlı sistemi şu durumlarda tutun:
- Uygulamanın
Sec-Fetch-Sitegöndermeyen tarayıcıları desteklemesi gerekir. Bkz . Tarayıcı desteği. - Uygulama, belirtecin içindeki ek verileri gidiş dönüş yapmak için kullanır IAntiforgeryAdditionalDataProvider .
- Güvenlik gözden geçirmesi veya uyumluluk gereksinimi, belirteç savunmasını bağımsız bir katman olarak belirtir.
Form tümleştirmesi, AJAX akışları, AntiforgeryOptions aracılığıyla yapılandırma ve IAntiforgery API'leri dahil olmak üzere token tabanlı sistemle ilgili ayrıntılar için ASP.NET Core’da İstek Sahteciliğini Önleme konusuna bakın.
Belirteç doğrulaması önceliklidir
Bir uygulama app.UseAntiforgery() çağırdığında, token tabanlı ara yazılım otomatik CSRF ara yazılımından sonra çalışır. Belirteç ara yazılımı, CSRF ara yazılımının kaydettiği herhangi bir sonucu temizler ve bunu belirteç doğrulamasının sonucuyla değiştirir. Belirteç sonucu kesindir:
- CSRF ara yazılımının geçersiz olarak işaretlediğini belirten bir istek, geçerli bir belirteç taşıyorsa geçerli olur.
- CSRF ara yazılımının izin verdiği bir istek, belirteci eksik veya geçersizse geçersiz olarak işaretlenir.
Bu sıralama, belirteç sistemini kullanan uygulamaların otomatik ara yazılım mevcut olmadan önce sahip oldukları uçtan uca davranışı görürken, belirteç kullanmayan uygulamaların CSRF ara yazılımının kararına geri dönmesi anlamına gelir.
Blazor statik sunucu tarafı işleme
Blazor statik sunucu tarafı işleme (SSR) uç noktaları aynı ertelenmiş modele katılır.
Razor Bileşenler uç noktası, üst akış ara katman yazılımı tarafından IAntiforgeryValidationFeature üzerine kaydedilen karara güvenir ve yalnızca bu karar geçersiz olduğunda bir form gönderimi için 400 - Bad Request döndürür. Uç nokta artık isteğin kendisini doğrulamaz.
Davranış, hangi ara yazılımların çalıştırıldığına bağlıdır:
-
app.UseAntiforgery()çağıran uygulamalar değiştirilmez. Belirteç tabanlı ara katman her isteği doğrular ve daha önce olduğu gibi oluşturulan formlar için sahteciliğe karşı belirteçler üretilir. - Çağırmayan
app.UseAntiforgery()uygulamalar bunun yerine otomatik CSRF ara yazılımı tarafından korunur. Bu yapılandırmada uç nokta, sonraki bir istekte belirteci doğrulayacak bir ara yazılım bulunmadığından sahteciliği önleme belirteci oluşturmayı atlar.
Bu, daha önce app.UseAntiforgery() öğesini kaldıran statik SSR için bir davranış değişikliğidir: artık korumasız bırakılmak yerine CSRF ara yazılımı tarafından korunur ve sahteciliği önleme belirteçleri üretmeyi durdurur. Geçiş kılavuzu için bkz. .NET 10'daki ASP.NET Core'dan .NET 11'deki ASP.NET Core'a Geçiş. Resmi uyumsuz değişiklik bildirimi için bkz. Blazor sunucu tarafı oluşturma, sahteciliğe karşı koruma doğrulamasını ara yazılıma erteler.
Troubleshooting
Belirti: Tarayıcıdan yapılan aynı kaynaklı istekler başarılı olur, ancak kaynaklar arası form POST istekleri gövde olmadan 400 - Bad Request döndürür.
Neden: CSRF ara yazılımı, farklı kaynaklar arası istek için geçersiz bir hüküm kaydetti ve MVC eylemi, Minimal API form bağlama işlemi veya Blazor SSR form gönderisi gibi bir form işleme bileşeni bu hükmü 400 - Bad Request ile uyguladı. Bu, formları işleyen uç noktalar için beklenen varsayılan davranıştır.
Çözünürlük: Senaryoya bağlı olarak aşağıdakilerden birini seçin:
- Arama kaynağı biliniyor ve güvenilirse CORS aracılığıyla izin verin.
- Uç noktaya tarayıcıdan erişilemiyorsa veya cookie dışı kimlik doğrulama kullanıyorsa, bunu ya da
.DisableAntiforgery()ile[IgnoreAntiforgeryToken]. - Uygulamanın tamamının hariç tutulması gerekiyorsa (örneğin, bir geçiş dönemi sırasında), global olarak devre dışı bırakın.
Tanılama: Ara yazılım, her geçersiz kararı Debug düzeyinde, Microsoft.AspNetCore.Antiforgery.CsrfProtectionMiddleware kategorisi altında ve CsrfValidationFailed olay adıyla günlüğe kaydeder.
Debug içinde bu kategori için appsettings.Development.json günlük kaydını etkinleştirin:
{
"Logging": {
"LogLevel": {
"Microsoft.AspNetCore.Antiforgery.CsrfProtectionMiddleware": "Debug"
}
}
}
Kaydedilen bir karar daha sonra günlükte şu şekilde görünür:
dbug: Microsoft.AspNetCore.Antiforgery.CsrfProtectionMiddleware[1]
Cross-origin CSRF protection marked request POST /widgets from origin 'https://attacker.example.com' as invalid.
Yerel olarak yeniden oluşturma: Bir form uç noktasına karşı farklı kaynaktan gelen bir tarayıcı isteğini benzetmek için, açıkça belirtilmiş bir curl üst bilgisiyle Origin kullanın:
curl -i -X POST https://localhost:{PORT}/widgets \
-H "Origin: https://attacker.example.com" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "name=test"
{PORT} değerini uygulamanın yerel HTTPS portuyla değiştirin.
400 - Bad Request, uç nokta kaydedilmiş kararı uygulayan formu bağladığı için gözlemlenir. Form dışı bir uç nokta, kararı okuyan hiçbir şey olmadığından normal yanıtını döndürür.
Origin üst bilgisi olmadan, aynı isteğe izin verilir çünkü curl, Sec-Fetch-Site üst bilgisini de göndermez ve bu iki üst bilgiden hiçbirini içermeyen bir istek, tarayıcı olmayan bir istemci olarak değerlendirilir.
Bu makalenin geri kalanında açıklanan belirteç tabanlı sahteciliğe karşı koruma sistemi, bu ara yazılımdan öncedir ve kullanılabilir olmaya devam etmektedir. Çoğu uygulama için otomatik koruma tek başına yeterlidir. Belirteç tabanlı sistemin ne zaman korunacağı ve nasıl geçiş yapılacağına ilişkin yönergeler için bkz.: .NET 10’daki ASP.NET Core’dan .NET 11’deki ASP.NET Core’a geçiş yapma.
ASP.NET Core'da Sahtecilikle Mücadele
Uyarı
ASP.NET Core, ASP.NET Core Veri Koruması kullanarak kötü amaçlı yazılımdan koruma uygular. Veri koruma yığını bir sunucu grubunda çalışacak şekilde yapılandırılmalıdır. Daha fazla bilgi için bkz . Veri korumasını yapılandırma.
Aşağıdaki API'lerden biri çağrıldığında, sahtecilik karşıtı ara yazılım bağımlılık enjeksiyonu konteynerine eklenir:
Daha fazla bilgi için Minimal API'lerle Sahteciliğe Karşı Koruma bölümüne bakın.
FormTagHelper, HTML form öğelerine sahtecilik önleme belirteçleri ekler. Bir dosyada Razor aşağıdaki işaretleme otomatik olarak kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form method="post">
<!-- ... -->
</form>
Benzer şekilde, IHtmlHelper.BeginForm formun yöntemi GET değilse varsayılan olarak antiforgery belirteçleri oluşturur.
HTML form öğeleri için otomatik sahte belirteç oluşturma işlemi, <form> etiketi method="post" özniteliğini içerdiğinde ve aşağıdakilerden biri doğru olduğunda gerçekleşir:
- Eylem özniteliği boş (
action=""). - Eylem özniteliği sağlanmadı (
<form method="post">).
HTML form öğeleri için kimlik doğrulama belirteçlerinin otomatik oluşturulması devre dışı bırakılabilir.
asp-antiforgeryözniteliği ile antiforgery belirteçlerini açıkça devre dışı bırakın.<form method="post" asp-antiforgery="false"> <!-- ... --> </form>Form öğesi Etiket Yardımcısı ! geri çevirme simgesi kullanılarak Etiket Yardımcıları'nı geri çevirmiş olur:
<!form method="post"> <!-- ... --> </!form>FormTagHelperöğesini görünümden kaldırın. Bir görünümdenFormTagHelperkaldırılabilir, bunun için Razor görünümüne aşağıdaki yönerge eklenmelidir.@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Not
Razor Sayfalar XSRF/CSRF'den otomatik olarak korunur. Daha fazla bilgi için bkz . XSRF/CSRF ve Razor Sayfalar.
CSRF saldırılarına karşı korumanın en yaygın yaklaşımı Eşitleyici Belirteci Deseni'ni (STP) kullanmaktır. Kullanıcı form verilerini içeren bir sayfa istediğinde STP kullanılır:
- Sunucu, geçerli kullanıcının kimliğiyle ilişkilendirilmiş bir belirteci istemciye gönderir.
- İstemci doğrulama için belirteci sunucuya geri gönderir.
- Sunucu kimliği doğrulanmış kullanıcının kimliğiyle eşleşmeyen bir belirteç alırsa istek reddedilir.
Belirteç benzersizdir ve öngörülemez. Belirteç, bir dizi isteğin düzgün sıralanmasını sağlamak için de kullanılabilir (örneğin, istek sırasının sağlanması: sayfa 1 > sayfa 2 > sayfa 3). ASP.NET Core MVC ve Razor Pages şablonlarındaki tüm formlar, sahtecilik önleyici jetonlar oluşturur. Aşağıdaki görünüm örnekleri çifti, kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
HTML yardımcısı <form> ile Etiket Yardımcıları kullanmadan bir @Html.AntiForgeryToken öğesine açıkça bir sahtecilik karşıtı belirteç ekleyin.
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Önceki durumların her birinde, ASP.NET Core aşağıdaki örneğe benzer bir gizli form alanı ekler:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core, kötü amaçlı yazılımdan koruma belirteçleriyle çalışmak için üç filtre içerir:
AddControllers ile antiforgery
ÇağrıAddControllersasla sahteciliğe karşı koruma belirteçlerini etkinleştirmez. AddControllersWithViews yerleşik sahtecilik önleme belirteci desteğine sahip olmak için çağrılmalıdır.
Birden çok tarayıcı sekmesi ve Eşitleyici Belirteci Deseni
Farklı kullanıcılar olarak oturum açan veya anonim olarak oturum açan birden çok sekme desteklenmez.
AntiforgeryOptions ile sahtecilik önleyiciyi yapılandırın
Uygulamanın AntiforgeryOptions dosyasını Program içinde özelleştirin.
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Aşağıdaki tabloda gösterildiği gibi cookie sınıfının özelliklerini kullanarak, sahteciliği önleme CookieBuilder özelliklerini ayarlayın.
| Seçenek | Açıklama |
|---|---|
| Cookie | Sahtecilik karşıtı tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler. |
| FormFieldName | Antiforgery sistemi tarafından görünümlerde sahteciliğe karşı belirteçleri oluşturmak için kullanılan gizli form alanının adı. |
| HeaderName | Sahtecilik önleme sistemi tarafından kullanılan başlığın adı. ise null, sistem yalnızca form verilerini dikkate alır. |
| SuppressXFrameOptionsHeader | Başlığın oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Başlık varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. Varsayılan değer false olarak ayarlanır. |
Bazı tarayıcılar güvenli olmayan uç noktaların 'güvenli' bayrağı olan tanımlama bilgilerini ayarlamasına veya 'güvenli' bayrağı ayarlanmış tanımlama bilgilerinin üzerine yazmasına izin vermez (daha fazla bilgi için bkz. Güvenli olmayan kaynaklardan 'güvenli' tanımlama bilgilerinin değiştirilmesini kaldırma). Güvenli ve güvensiz uç noktaların karıştırılması uygulamalarda yaygın bir senaryo olduğundan, ASP.NET Core, sahtecilik karşıtı gibi bazı tanımlama bilgilerindeki güvenli ilke kısıtlamasını, cookie'nin cookie'sini SecurePolicy olarak ayarlayarak gevşetir. Kötü amaçlı bir kullanıcı bir sahteciliğe karşı cookiekoruma çalsa bile, genellikle bir form alanı (daha yaygın) veya ayrı bir istek üst bilgisi (daha az yaygın) ve kimlik doğrulaması cookiearacılığıyla gönderilen sahteciliğe karşı koruma belirtecini de çalmalıdır. Kimlik doğrulaması veya yetkilendirmeyle ilgili tanımlama bilgileri, CookieSecurePolicy.None'dan daha güçlü bir ilke kullanır.
İsteğe bağlı olarak, uygulamanın cookie dosyasında aşağıdaki Development özellik ayarıyla, yalnızca HTTPS üzerinden Güvenli Yuva Katmanı (SSL) kullanarak ortamlarda olmayan ortamlardaki kötü amaçlı AntiforgeryOptions.CookieProgram yazılımdan korumanın güvenliğini sağlayabilirsiniz:
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
Daha fazla bilgi için bkz. CookieAuthenticationOptions.
IAntiforgery ile antiforgery belirteçleri oluşturma
IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar.
IAntiforgery, Program.cs kullanılarak WebApplication.Services istenebilir. Aşağıdaki örnek, uygulamanın giriş sayfasındaki ara yazılımı kullanarak bir kötü amaçlı yazılımdan koruma belirteci oluşturur ve bunu yanıtta cookieolarak gönderir:
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);
});
Yukarıdaki örnek, cookie adlı bir XSRF-TOKEN ayarlar. İstemci bunu cookie okuyabilir ve değerini AJAX isteklerine başlık olarak ekleyebilir. Örneğin, Angular, varsayılan olarak bir adı okuyan yerleşik XSRF koruması cookie içerirXSRF-TOKEN.
Antiforgery doğrulaması gerektirir
ValidateAntiForgeryToken eylem filtresi tek bir eyleme, denetleyiciye veya genel olarak uygulanabilir. bu filtrenin uygulandığı eylemlere yapılan istekler, istek geçerli bir kötü amaçlı yazılımdan koruma belirteci içermediği sürece engellenir:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
Bu ValidateAntiForgeryToken özniteliği, HTTP GET istekleri dahil olmak üzere, işaretlediği eylem yöntemleri için isteklerde bir belirteç gerektirir. Uygulamanın kontrolörlerinde ValidateAntiForgeryToken özniteliği uygulanmışsa, bu öznitelik IgnoreAntiforgeryToken özniteliği ile geçersiz kılınabilir.
Güvenli olmayan HTTP yöntemleri için sahtecilik karşıtı jetonları otomatik olarak doğrula.
AutoValidateAntiforgeryTokenValidateAntiForgeryToken çalışır:
- GET
- BAŞ
- SEÇENEKLER
- TRACE
API dışı senaryolar için geniş kapsamlı olarak kullanılmasını AutoValidateAntiforgeryToken öneririz. Bu öznitelik POST eylemlerinin varsayılan olarak korunmasını sağlar. Bunun alternatifi, tek tek eylem yöntemlerine uygulanmadığı sürece, varsayılan olarak sahtekarlık önleme belirteçlerini yoksaymaktır. Post eylem yönteminin yanlışlıkla korumasız bırakılması ve uygulamayı CSRF saldırılarına karşı savunmasız bırakma olasılığı bu senaryoda daha yüksektir. Tüm POST'ler, kötü amaçlı yazılımdan koruma belirtecini göndermelidir.
API'ler belirtecin parçası olmayancookie kısmını göndermek için otomatik bir mekanizmaya sahip değildir. Uygulama büyük olasılıkla istemci kodu uygulamasına bağlıdır. Aşağıda bazı örnekler gösterilmiştir:
Sınıf düzeyi örneği:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Genel örnek:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Genel veya denetleyici sahtecilik önleme özniteliklerini geçersiz kılma
IgnoreAntiforgeryToken filtresi, belirli bir eylem (veya denetleyici) için bir antiforgery belirteci gereksinimini ortadan kaldırmak için kullanılır. Uygulandığında, bu filtre, daha yüksek bir düzeyde (ValidateAntiForgeryToken veya AutoValidateAntiforgeryToken filtrelerinde) belirtilen genel veya denetleyici düzeyindeki filtreleri geçersiz kılar.
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Kimlik doğrulaması sonrasında belirteçleri yenileme
Belirteçler, kullanıcının kimliği doğrulandıktan sonra kullanıcıyı bir görünüme veya Razor Sayfalar sayfasına yönlendirerek yenilenmelidir.
JavaScript, AJAX ve SPA'lar
Geleneksel HTML tabanlı uygulamalarda, kötü amaçlı yazılımdan koruma belirteçleri gizli form alanları kullanılarak sunucuya geçirilir. Modern JavaScript tabanlı uygulamalarda ve SPA'larda program aracılığıyla birçok istek yapılır. Bu AJAX istekleri, belirteci göndermek için istek başlıkları veya tanımlama bilgileri gibi diğer teknikleri kullanabilir.
Kimlik doğrulama belirteçlerini depolamak ve sunucuda API isteklerini kimliğini doğrulamak için tanımlama bilgileri kullanılıyorsa, CSRF olası bir sorundur. Belirteci depolamak için yerel depolama kullanılıyorsa, yerel depolamadaki değerler her istekle birlikte sunucuya otomatik olarak gönderilmediğinden CSRF güvenlik açığı giderilebilir. İstemcide kötü amaçlı yazılımdan koruma belirtecini depolamak için yerel depolamayı kullanmak ve belirteci istek üst bilgisi olarak göndermek önerilen bir yaklaşımdır.
Blazor
Daha fazla bilgi için bkz . ASP.NET Çekirdek Blazor kimlik doğrulaması ve yetkilendirme.
JavaScript
JavaScript'i görünümlerle kullanarak belirteç, görünümün içinden bir hizmet kullanılarak oluşturulabilir. IAntiforgery hizmetini görünüme aktar ve GetAndStoreTokens çağır:
@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>
}
Yukarıdaki örnekte, AJAX POST üst bilgisinin gizli alan değerini okumak için JavaScript kullanılır.
Bu yaklaşım, sunucudan tanımlama bilgileri ayarlama veya bunları istemciden okuma gereksinimini ortadan kaldırır. Ancak, IAntiforgery hizmeti enjekte etmek mümkün değilse, tanımlama bilgilerindeki belirteçlere erişmek için JavaScript kullanın.
- Sunucuya yöneltilen ek bir istekte genellikle erişim belirteçlerine ulaşılır
same-origin. - Belirtecin değerini içeren cookie'yi kullanarak bir üst bilgi oluşturun.
Betiğin belirteç adlı X-XSRF-TOKEN üst bilgiye sahip bir istek gönderdiğini varsayarsak, sahtecilik önleme hizmetini X-XSRF-TOKEN üst bilgiyi arayacak şekilde yapılandırın.
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Aşağıdaki örnek, istek belirtecini JavaScript tarafından okunabilecek bir öğeye (cookie) yazan korumalı bir uç nokta ekler.
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();
Aşağıdaki örnekte JavaScript, belirteci almak ve uygun üst bilgiyle başka bir istekte bulunmak üzere AJAX isteğinde bulunmak için kullanılır:
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}`
}
Not
Hem istek üst bilgisinde hem de form yükünde sahtecilik engelleme belirteci sağlandığında, yalnızca üst bilgideki belirteç doğrulanır.
Minimal API'lerle sahteciliğin önlenmesi
AddAntiforgery ve fonksiyonlarını DI'ye sahtecilik önleme hizmetlerini kaydetmek için çağırın. Antiforgery belirteçleri siteler arası istek sahteciliği saldırılarını azaltmak için kullanılır.
var builder = WebApplication.CreateBuilder();
builder.Services.AddAntiforgery();
var app = builder.Build();
app.UseAntiforgery();
app.MapGet("/", () => "Hello World!");
app.Run();
Kötü amaçlı yazılımdan koruma ara yazılımı:
- , istek işlem hattının geri kalanının yürütülmesini kısa devre yapmaz mı?.
- Mevcut istekteki IAntiforgeryValidationFeature üzerine HttpContext.Features'ı ayarlar.
Sahteciliği önleme belirteci yalnızca aşağıdaki durumlarda doğrulanır:
- Uç nokta, IAntiforgeryMetadatabağlamında
RequiresValidation=trueuygulayan meta verileri içerir. - Uç noktayla ilişkili HTTP yöntemi POST, PUT veya PATCH türünde ilgili bir HTTP yöntemidir .
- İstek geçerli bir uç noktayla ilişkilendirildi.
Sahteciliği önleme ara katmanı, istek işlem hattını kısa devreye uğratmaz. Belirteç doğrulaması başarısız olsa bile uç nokta kodu her zaman çalışır. Belirteç doğrulamasının sonucunu gözlemlemek için IAntiforgeryValidationFeature içindeki HttpContext.Features çözümleyin ve hata ayrıntıları için IsValid özelliğini veya Error özelliğini inceleyin. Uç noktalar başarısız olan kötü amaçlı yazılımdan koruma doğrulaması için özel işleme gerektirdiğinde bu yaklaşım kullanışlıdır.
Not: El ile etkinleştirildiğinde, kullanıcı kimliği doğrulanmamış olduğunda form verilerinin okunmasını önlemek için kimlik doğrulama ve yetkilendirme ara yazılımından sonra kötü amaçlı yazılımdan koruma ara yazılımının çalışması gerekir.
Varsayılan olarak, form verilerini kabul eden Minimal API'ler, antiforgery belirteç doğrulaması gerektirir ve belirteç doğrulama başarılı olmazsa uygulama kodunu çalıştırmadan önce başarısızlıkla sonuçlanır.
Aşağıdaki GenerateForm yöntemi göz önünde bulundurun:
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>
";
}
Yukarıdaki kod üç bağımsız değişkene sahiptir: eylem, sahteciliğe karşı koruma belirteci ve belirtecin kullanılıp kullanılmayacağını gösteren bir bool .
Aşağıdaki örneği göz önünde bulundurun:
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>
";
}
}
Önceki kodda şu gönderileri gönder:
-
/todogeçerli bir sahtecilik önleme belirteci gerektirir. -
/todo2geçerli bir antiforgery belirteci gerektirmez çünkü çağrılır.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
Uyarı
Çağırma, .DisableAntiforgery() uç nokta için siteler arası istek sahteciliği (CSRF) korumasını devre dışı bırakır. Bu yalnızca bir uç nokta CSRF saldırılarına karşı savunmasız olmadığında kullanılmalıdır, örneğin:
- Tarayıcıdan çağrılamayan uç noktalar (örneğin, iç API'ler)
- Tabanlı olmayancookie kimlik doğrulamasıyla güvenliği sağlanan uç noktalar (örneğin, taşıyıcı belirteçleri veya API anahtarları)
- Kullanıcı çerezlerine güvenmeyen iç veya altyapı uç noktaları
Kimlik doğrulaması için tanımlama bilgilerini kullanan veya kullanıcı tarafından gönderilen form verilerini işleyen tarayıcı tarafından erişilebilen uç noktalar için kötü amaçlı yazılımdan koruma doğrulamasını devre dışı bırakmayın, bu durum uygulamanızı CSRF saldırılarına maruz bırakır.
Gönderi:
-
/todosahtecilik önleme belirteci geçerli olduğundan, uç nokta tarafından/oluşturulan formdan başarıyla çalışır. -
/todotarafından oluşturulan formda antiforgery dahil edilmediği için/SkipTokenbaşarısız oluyor. -
/todo2sahtecilik önleme gerektirilmediğinden,/DisableAntiforgeryuç noktası tarafından oluşturulan formdan başarılı olur.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));
app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
.DisableAntiforgery();
Form geçerli bir kötü amaçlı yazılımdan koruma belirteci olmadan gönderildiğinde:
-
Developmentortamında bir istisna atılır. -
ProductionOrtamda bir ileti günlüğe kaydedilir.
HTTP yöntemi sınırlamaları ve HttpMethodOverrideMiddleware etkileşimi
Ara yazılım tabanlı sahteciliğe karşı koruma yolunda, AntiforgeryMiddleware ve UseAntiforgery() sahteciliğe karşı koruma belirteçlerini yalnızca HTTP POST, PUT ve PATCH istekleri için doğrular.
DELETE gibi diğer HTTP yöntemleri otomatik olarak doğrulanmaz.
Diğer HTTP yöntemleri için sahteciliğe karşı belirteçleri doğrulamak üzere, DI'den IAntiforgery alın ve ValidateRequestAsync veya IsRequestValidAsync yöntemini açıkça çağırın:
app.MapDelete("/item/{id}", async (int id, IAntiforgery antiforgery, HttpContext context) =>
{
await antiforgery.ValidateRequestAsync(context);
// Process the DELETE request
});
Uyarı
HttpMethodOverrideMiddleware, FormFieldName ile yapılandırıldığında (form alanı modu) ve AntiforgeryMiddleware'den önce yerleştirildiğinde, bir POST isteği DELETE (veya doğrulanmayan başka bir metot) olarak geçersiz kılınabilir. Yalnızca AntiforgeryMiddleware POST, PUT ve PATCH doğrulandığından geçersiz kılınan istek, sahteciliğe karşı doğrulamayı atlar.
Bu uç noktaları korumak için:
- İşlem hattınız buna izin veriyorsa,
HttpMethodOverrideMiddlewareöğesini antiforgery doğrulamasından sonra yerleştirmeyi tercih edin. - Sahteciliğe karşı doğrulamaya dayanan uç noktalar için form alanı geçersiz kılmalarından kaçının.
- Form alanı geçersiz kılmasının önce çalışması gerekiyorsa, sahteciliğe karşı koruma belirtecini
IAntiforgery.ValidateRequestAsynckullanarak açıkça doğrulayın.
Yapılandırma ayrıntıları için bkz. ASP.NET Core ara yazılım.
Windows kimlik doğrulaması ve sahtecilik önleyici tanımlama bilgileri
Windows Kimlik Doğrulaması kullanılırken, uygulama uç noktalarının tanımlama bilgileriyle aynı şekilde CSRF saldırılarına karşı korunması gerekir. Tarayıcı, kimlik doğrulama bağlamını sunucuya örtük olarak gönderir ve uç noktaların CSRF saldırılarına karşı korunması gerekir.
Sahtecilik önlemeyi genişletme
IAntiforgeryAdditionalDataProvider türü, geliştiricilerin her belirteçte ek verileri gidip getirerek anti-CSRF sisteminin davranışını genişletmesine olanak tanır. Bir GetAdditionalData alan belirteci her oluşturulduğunda yöntemi çağrılır ve döndürülen değer oluşturulan belirtecin içine eklenir. Uygulayıcı bir zaman damgası, bir nonce veya başka bir değer döndürebilir ve daha sonra, token doğrulandığında bu veriyi doğrulamak için ValidateAdditionalData çağırabilir. İstemcinin kullanıcı adı oluşturulan belirteçlere zaten eklenmiş olduğundan bu bilgileri eklemenize gerek yoktur. Belirteç ek veriler içeriyorsa ancak yapılandırılmamışsa IAntiForgeryAdditionalDataProvider , ek veriler doğrulanmaz.
Ek kaynaklar
Siteler arası istek sahteciliği (XSRF veya CSRF olarak da bilinir), kötü amaçlı bir web uygulamasının istemci tarayıcısı ile bu tarayıcıya güvenen bir web uygulaması arasındaki etkileşimi etkilediği web'de barındırılan uygulamalara yönelik bir saldırıdır. Bu saldırılar mümkündür çünkü web tarayıcıları bir web sitesine her istekle birlikte bazı kimlik doğrulama belirteçleri türlerini otomatik olarak gönderir. Saldırı, kullanıcının daha önce kimliği doğrulanmış oturumundan yararlandığından, bu açıklardan yararlanma biçimi tek tıklamayla saldırı veya oturum sürme olarak da bilinir.
CSRF saldırısı örneği:
Bir kullanıcı form kimlik doğrulamasını kullanarak
www.good-banking-site.example.comsitesine oturum açar. Sunucu kullanıcının kimliğini doğrular ve kimlik doğrulaması cookieiçeren bir yanıt gönderir. Site, geçerli bir kimlik doğrulaması cookieile aldığı tüm isteklere güvendiği için saldırıya açık durumdadır.Kullanıcı kötü amaçlı bir siteyi ziyaret etti.
www.bad-crook-site.example.comKötü amaçlı site,
www.bad-crook-site.example.comaşağıdaki örneğe benzer bir HTML formu içerir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.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>Formun
actionkötü amaçlı siteye değil, güvenlik açığı bulunan siteye gönderildiğini fark edin. Bu, CSRF'nin "siteler arası" bölümüdür.Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı cookie için kimlik doğrulamasını
www.good-banking-site.example.comotomatik olarak içerir.İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır
www.good-banking-site.example.comve kimliği doğrulanmış bir kullanıcının gerçekleştirmesine izin verilen tüm eylemleri gerçekleştirebilir.
Kullanıcının formu göndermek için düğmeyi seçtiği senaryoya ek olarak, kötü amaçlı site şunları yapabilir:
- Formu otomatik olarak gönderen bir betik çalıştırın.
- Form gönderimini AJAX isteği olarak gönderin.
- CSS kullanarak formu gizleyin.
Bu alternatif senaryolar, başlangıçta kötü amaçlı siteyi ziyaret etmekten başka kullanıcıdan herhangi bir eylem veya giriş gerektirmez.
HTTPS kullanmak CSRF saldırısını engellemez. Kötü amaçlı site, güvenli olmayan bir istek gönderebildiği kadar kolay bir şekilde https://www.good-banking-site.example.com/ isteği de gönderebilir.
Bazı saldırılar GET isteklerine yanıt veren uç noktaları hedefler ve bu durumda eylemi gerçekleştirmek için bir görüntü etiketi kullanılabilir. Bu saldırı biçimi, görüntülere izin veren ancak JavaScript'i engelleyen forum sitelerinde yaygındır. Değişkenlerin veya kaynakların değiştirildiği GET isteklerinde durumu değiştiren uygulamalar kötü amaçlı saldırılara karşı savunmasızdır. Durumu değiştiren GET istekleri güvenli değildir. Get isteğinde hiçbir zaman durumu değiştirmemek en iyi yöntemdir.
Kimlik doğrulaması için tanımlama bilgileri kullanan web uygulamalarına CSRF saldırıları mümkündür çünkü:
- Tarayıcılar, web uygulaması tarafından verilen çerezleri depolar.
- Depolanan tanımlama bilgileri, kimliği doğrulanmış kullanıcılar için oturum tanımlama bilgilerini içerir.
- Tarayıcılar, bir etki alanıyla ilişkili tüm tanımlama bilgilerini, uygulama isteğinin tarayıcıda nasıl oluşturulduğundan bağımsız olarak her istekte web uygulamasına gönderir.
Ancak CSRF saldırıları, tanımlama bilgilerini kötüye kullanmakla sınırlı değildir. Örneğin, Temel ve Özet kimlik doğrulaması da savunmasızdır. Kullanıcı Temel veya Özet kimlik doğrulamasıyla oturum açtığında, oturum bitene kadar tarayıcı kimlik bilgilerini otomatik olarak gönderir.
Bu bağlamda oturum, kullanıcının kimliğinin doğrulandığı istemci tarafı oturumuna başvurur. Sunucu tarafı oturumlarıyla veya ASP.NET Core oturum ara yazılımıyla ilgisizdir.
Kullanıcılar, önlemler alarak CSRF güvenlik açıklarına karşı koruma sağlayabilir:
- Web uygulamalarını kullanmayı bitirdiğinizde oturumunu kapatın.
- Tarayıcı tanımlama bilgilerini düzenli aralıklarla temizleyin.
Ancak CSRF güvenlik açıkları, son kullanıcıyla değil, temel olarak web uygulamasıyla ilgili bir sorundur.
Kimlik doğrulamasının temelleri
Cookietabanlı kimlik doğrulaması, popüler bir kimlik doğrulaması biçimidir. Özellikle Tek Sayfalı Uygulamalar (SPA' lar) için belirteç tabanlı kimlik doğrulama sistemlerinin popülerliği artmaktadır.
Cookietabanlı kimlik doğrulaması
Kullanıcı kullanıcı adı ve parolasını kullanarak kimlik doğrulaması yaptığı zaman, kimlik doğrulaması ve yetkilendirme için kullanılabilecek bir kimlik doğrulama bileti içeren bir belirteç verilir. Belirteç, istemcinin yaptığı her istekle gönderilen bir cookie olarak depolanır. Bu cookie öğesinin oluşturulması ve doğrulanması, cookie kimlik doğrulama ara yazılımı tarafından gerçekleştirilir. Arayazılım, bir kullanıcı kimliğini şifrelenmiş bir olarak seri hale getirmektedir. Sonraki isteklerde ara yazılım cookie'yi doğrular, kimliği yeniden oluşturur ve kimliği HttpContext.User özelliğine atar.
Belirteç tabanlı kimlik doğrulaması
Bir kullanıcının kimliği doğrulandığında, ona bir belirteç verilir (bir sahteciliğe karşı koruma belirteci değil). Belirteç, haklar biçiminde kullanıcı bilgilerini veya uygulamada tutulan kullanıcı durumuna işaret eden bir referans belirteci içerir. Kullanıcı kimlik doğrulaması gerektiren bir kaynağa erişmeye çalıştığında belirteç, Taşıyıcı belirteci biçiminde ek yetkilendirme üst bilgisi ile uygulamaya gönderilir. Bu yaklaşım uygulamayı durumsuz hale getirir. Sonraki her istekte, belirteç sunucu tarafı doğrulama isteğine geçirilir. Bu belirteç şifrelenmez; kodlanır. Sunucuda belirtecin kodu bilgilerine erişmek için çözülmektedir. Sonraki isteklerde belirteci göndermek için belirteci tarayıcının yerel depolama alanında depolayın. Jetonu tarayıcı yerel depolama alanına yerleştirmek, geri almak ve taşıyıcı jeton olarak kullanmak, CSRF saldırılarına karşı koruma sağlar. Ancak, uygulama XSS aracılığıyla betik eklemeye veya güvenliği aşılmış bir dış javascript dosyasına karşı savunmasız olursa, siber saldırı yerel depolamadan herhangi bir değeri alabilir ve kendilerine gönderebilir. ASP.NET Core varsayılan olarak değişkenlerden gelen tüm sunucu tarafı çıkışlarını kodlayarak XSS riskini azaltır. Html.Raw veya özel kodu güvenilmeyen girişle kullanarak bu davranışı geçersiz kılarsanız XSS riskini artırabilirsiniz.
Belirteç tarayıcının yerel depolama alanında depolanıyorsa CSRF güvenlik açığı konusunda endişelenmeyin. CSRF, belirtecin bir cookie içinde depolandığı durumlarda sorundur. Daha fazla bilgi için GitHub konusuna bakın: SPA kodu örneği iki çerez ekler.
Bir alan adında barındırılan birden fazla uygulama
Paylaşılan barındırma ortamları oturum ele geçirme, oturum açma CSRF'leri ve diğer saldırılara karşı savunmasızdır.
ve example1.contoso.net farklı konaklar olsa example2.contoso.net da, etki alanı altındaki *.contoso.net konaklar arasında örtük bir güven ilişkisi vardır. Bu örtük güven ilişkisi, potansiyel olarak güvenilmeyen konakların birbirlerinin çerezlerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP çerezleri için geçerli olmayabilir).
Aynı etki alanında barındırılan uygulamalar arasındaki güvenilir tanımlama bilgilerini istismar eden saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her bir uygulama kendi alanında barındırıldığında, istismar edilecek örtük bir güven ilişkisi yoktur.
ASP.NET Core'da Sahtecilikle Mücadele
Uyarı
ASP.NET Core, ASP.NET Core Veri Koruması kullanarak kötü amaçlı yazılımdan koruma uygular. Veri koruma yığını bir sunucu grubunda çalışacak şekilde yapılandırılmalıdır. Daha fazla bilgi için bkz . Veri korumasını yapılandırma.
Aşağıdaki API'lerden biri çağrıldığında, sahtecilik karşıtı ara yazılım bağımlılık enjeksiyonu konteynerine eklenir:
FormTagHelper, HTML form öğelerine sahtecilik önleme belirteçleri ekler. Bir dosyada Razor aşağıdaki işaretleme otomatik olarak kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form method="post">
<!-- ... -->
</form>
Benzer şekilde, IHtmlHelper.BeginForm formun yöntemi GET değilse varsayılan olarak antiforgery belirteçleri oluşturur.
HTML form öğeleri için otomatik sahte belirteç oluşturma işlemi, <form> etiketi method="post" özniteliğini içerdiğinde ve aşağıdakilerden biri doğru olduğunda gerçekleşir:
- Eylem özniteliği boş (
action=""). - Eylem özniteliği sağlanmadı (
<form method="post">).
HTML form öğeleri için kimlik doğrulama belirteçlerinin otomatik oluşturulması devre dışı bırakılabilir.
asp-antiforgeryözniteliği ile antiforgery belirteçlerini açıkça devre dışı bırakın.<form method="post" asp-antiforgery="false"> <!-- ... --> </form>Form öğesi Etiket Yardımcısı ! geri çevirme simgesi kullanılarak Etiket Yardımcıları'nı geri çevirmiş olur:
<!form method="post"> <!-- ... --> </!form>FormTagHelperöğesini görünümden kaldırın. Bir görünümdenFormTagHelperkaldırılabilir, bunun için Razor görünümüne aşağıdaki yönerge eklenmelidir.@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Not
Razor Sayfalar XSRF/CSRF'den otomatik olarak korunur. Daha fazla bilgi için bkz . XSRF/CSRF ve Razor Sayfalar.
CSRF saldırılarına karşı savunmaya yönelik en yaygın yaklaşım, Eşitleyici Belirteci Deseni'ni (STP) kullanmaktır. Kullanıcı form verilerini içeren bir sayfa istediğinde STP kullanılır:
- Sunucu, geçerli kullanıcının kimliğiyle ilişkilendirilmiş bir belirteci istemciye gönderir.
- İstemci doğrulama için belirteci sunucuya geri gönderir.
- Sunucu kimliği doğrulanmış kullanıcının kimliğiyle eşleşmeyen bir belirteç alırsa istek reddedilir.
Belirteç benzersizdir ve öngörülemez. Belirteç, bir dizi isteğin düzgün sıralanmasını sağlamak için de kullanılabilir (örneğin, istek sırasının sağlanması: sayfa 1 > sayfa 2 > sayfa 3). ASP.NET Core MVC ve Razor Pages şablonlarındaki tüm formlar, sahtecilik önleyici jetonlar oluşturur. Aşağıdaki görünüm örnekleri çifti, kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
HTML yardımcısı <form> ile Etiket Yardımcıları kullanmadan bir @Html.AntiForgeryToken öğesine açıkça bir sahtecilik karşıtı belirteç ekleyin.
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Önceki durumların her birinde, ASP.NET Core aşağıdaki örneğe benzer bir gizli form alanı ekler:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core, kötü amaçlı yazılımdan koruma belirteçleriyle çalışmak için üç filtre içerir:
AddControllers ile antiforgery
ÇağrıAddControllersasla sahteciliğe karşı koruma belirteçlerini etkinleştirmez. AddControllersWithViews yerleşik sahtecilik önleme belirteci desteğine sahip olmak için çağrılmalıdır.
Birden çok tarayıcı sekmesi ve Eşitleyici Belirteci Deseni
Eşitleyici Belirteci Deseni ile yalnızca en son yüklenen sayfa geçerli bir kötü amaçlı yazılım önleme belirteci içerir. Birden çok sekme kullanmak sorunlu olabilir. Örneğin, bir kullanıcı birden çok sekme açarsa:
- Yalnızca en son yüklenen sekme geçerli bir kötü amaçlı yazılımdan koruma belirteci içerir.
- Daha önce yüklenen sekmelerden yapılan istekler bir hatayla başarısız olur:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Bu bir sorun oluşturuyorsa alternatif CSRF koruma desenlerini göz önünde bulundurun.
AntiforgeryOptions ile sahtecilik önleyiciyi yapılandırın
Uygulamanın AntiforgeryOptions dosyasını Program içinde özelleştirin.
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Aşağıdaki tabloda gösterildiği gibi cookie sınıfının özelliklerini kullanarak, sahteciliği önleme CookieBuilder özelliklerini ayarlayın.
| Seçenek | Açıklama |
|---|---|
| Cookie | Sahtecilik karşıtı tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler. |
| FormFieldName | Antiforgery sistemi tarafından görünümlerde sahteciliğe karşı belirteçleri oluşturmak için kullanılan gizli form alanının adı. |
| HeaderName | Sahtecilik önleme sistemi tarafından kullanılan başlığın adı. ise null, sistem yalnızca form verilerini dikkate alır. |
| SuppressXFrameOptionsHeader | Başlığın oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Başlık varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. Varsayılan değer false olarak ayarlanır. |
Bazı tarayıcılar güvenli olmayan uç noktaların 'güvenli' bayrağı olan tanımlama bilgilerini ayarlamasına veya 'güvenli' bayrağı ayarlanmış tanımlama bilgilerinin üzerine yazmasına izin vermez (daha fazla bilgi için bkz. Güvenli olmayan kaynaklardan 'güvenli' tanımlama bilgilerinin değiştirilmesini kaldırma). Güvenli ve güvensiz uç noktaların karıştırılması uygulamalarda yaygın bir senaryo olduğundan, ASP.NET Core, sahtecilik karşıtı gibi bazı tanımlama bilgilerindeki güvenli ilke kısıtlamasını, cookie'nin cookie'sini SecurePolicy olarak ayarlayarak gevşetir. Kötü amaçlı bir kullanıcı bir sahteciliğe karşı cookiekoruma çalsa bile, genellikle bir form alanı (daha yaygın) veya ayrı bir istek üst bilgisi (daha az yaygın) ve kimlik doğrulaması cookiearacılığıyla gönderilen sahteciliğe karşı koruma belirtecini de çalmalıdır. Kimlik doğrulaması veya yetkilendirmeyle ilgili tanımlama bilgileri, CookieSecurePolicy.None'dan daha güçlü bir ilke kullanır.
İsteğe bağlı olarak, uygulamanın cookie dosyasında aşağıdaki Development özellik ayarıyla, yalnızca HTTPS üzerinden Güvenli Yuva Katmanı (SSL) kullanarak ortamlarda olmayan ortamlardaki kötü amaçlı AntiforgeryOptions.CookieProgram yazılımdan korumanın güvenliğini sağlayabilirsiniz:
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
Daha fazla bilgi için bkz. CookieAuthenticationOptions.
IAntiforgery ile antiforgery belirteçleri oluşturma
IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar.
IAntiforgery, Program.cs kullanılarak WebApplication.Services istenebilir. Aşağıdaki örnek, uygulamanın giriş sayfasındaki ara yazılımı kullanarak bir kötü amaçlı yazılımdan koruma belirteci oluşturur ve bunu yanıtta cookieolarak gönderir:
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);
});
Yukarıdaki örnek, cookie adlı bir XSRF-TOKEN ayarlar. İstemci bunu cookie okuyabilir ve değerini AJAX isteklerine başlık olarak ekleyebilir. Örneğin, Angular, varsayılan olarak bir adı okuyan yerleşik XSRF koruması cookie içerirXSRF-TOKEN.
Antiforgery doğrulaması gerektirir
ValidateAntiForgeryToken eylem filtresi tek bir eyleme, denetleyiciye veya genel olarak uygulanabilir. bu filtrenin uygulandığı eylemlere yapılan istekler, istek geçerli bir kötü amaçlı yazılımdan koruma belirteci içermediği sürece engellenir:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
Bu ValidateAntiForgeryToken özniteliği, HTTP GET istekleri dahil olmak üzere, işaretlediği eylem yöntemleri için isteklerde bir belirteç gerektirir. Uygulamanın kontrolörlerinde ValidateAntiForgeryToken özniteliği uygulanmışsa, bu öznitelik IgnoreAntiforgeryToken özniteliği ile geçersiz kılınabilir.
Güvenli olmayan HTTP yöntemleri için sahtecilik karşıtı jetonları otomatik olarak doğrula.
AutoValidateAntiforgeryTokenValidateAntiForgeryToken çalışır:
- GET
- BAŞ
- SEÇENEKLER
- TRACE
API dışı senaryolar için geniş kapsamlı olarak kullanılmasını AutoValidateAntiforgeryToken öneririz. Bu öznitelik POST eylemlerinin varsayılan olarak korunmasını sağlar. Bunun alternatifi, tek tek eylem yöntemlerine uygulanmadığı sürece, varsayılan olarak sahtekarlık önleme belirteçlerini yoksaymaktır. Post eylem yönteminin yanlışlıkla korumasız bırakılması ve uygulamayı CSRF saldırılarına karşı savunmasız bırakma olasılığı bu senaryoda daha yüksektir. Tüm POST'ler, kötü amaçlı yazılımdan koruma belirtecini göndermelidir.
API'ler belirtecin parçası olmayancookie kısmını göndermek için otomatik bir mekanizmaya sahip değildir. Uygulama büyük olasılıkla istemci kodu uygulamasına bağlıdır. Aşağıda bazı örnekler gösterilmiştir:
Sınıf düzeyi örneği:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Genel örnek:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Genel veya denetleyici sahtecilik önleme özniteliklerini geçersiz kılma
IgnoreAntiforgeryToken filtresi, belirli bir eylem (veya denetleyici) için bir antiforgery belirteci gereksinimini ortadan kaldırmak için kullanılır. Uygulandığında, bu filtre, daha yüksek bir düzeyde (ValidateAntiForgeryToken veya AutoValidateAntiforgeryToken filtrelerinde) belirtilen genel veya denetleyici düzeyindeki filtreleri geçersiz kılar.
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Kimlik doğrulaması sonrasında belirteçleri yenileme
Belirteçler, kullanıcının kimliği doğrulandıktan sonra kullanıcıyı bir görünüme veya Razor Sayfalar sayfasına yönlendirerek yenilenmelidir.
JavaScript, AJAX ve SPA'lar
Geleneksel HTML tabanlı uygulamalarda, kötü amaçlı yazılımdan koruma belirteçleri gizli form alanları kullanılarak sunucuya geçirilir. Modern JavaScript tabanlı uygulamalarda ve SPA'larda program aracılığıyla birçok istek yapılır. Bu AJAX istekleri, belirteci göndermek için başka teknikler (istek üst bilgileri veya tanımlama bilgileri gibi) kullanabilir.
Kimlik doğrulama belirteçlerini depolamak ve sunucuda API isteklerini kimliğini doğrulamak için tanımlama bilgileri kullanılıyorsa, CSRF olası bir sorundur. Belirteci depolamak için yerel depolama kullanılıyorsa, yerel depolamadaki değerler her istekle birlikte sunucuya otomatik olarak gönderilmediğinden CSRF güvenlik açığı giderilebilir. İstemcide kötü amaçlı yazılımdan koruma belirtecini depolamak için yerel depolamayı kullanmak ve belirteci istek üst bilgisi olarak göndermek önerilen bir yaklaşımdır.
JavaScript
JavaScript'i görünümlerle kullanarak belirteç, görünümün içinden bir hizmet kullanılarak oluşturulabilir. IAntiforgery hizmetini görünüme aktar ve GetAndStoreTokens çağır:
@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>
}
Yukarıdaki örnekte, AJAX POST üst bilgisinin gizli alan değerini okumak için JavaScript kullanılır.
Bu yaklaşım, sunucudan tanımlama bilgileri ayarlama veya bunları istemciden okuma gereksinimini ortadan kaldırır. Ancak, IAntiforgery hizmeti enjekte etmek mümkün değilse, tanımlama bilgilerindeki belirteçlere erişmek için JavaScript kullanın.
- Sunucuya yöneltilen ek bir istekte genellikle erişim belirteçlerine ulaşılır
same-origin. - Belirtecin değerini içeren cookie'yi kullanarak bir üst bilgi oluşturun.
Betiğin belirteç adlı X-XSRF-TOKEN üst bilgiye sahip bir istek gönderdiğini varsayarsak, sahtecilik önleme hizmetini X-XSRF-TOKEN üst bilgiyi arayacak şekilde yapılandırın.
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Aşağıdaki örnek, istek belirtecini JavaScript tarafından okunabilecek bir öğeye (cookie) yazan korumalı bir uç nokta ekler.
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();
Aşağıdaki örnekte JavaScript, belirteci almak ve uygun üst bilgiyle başka bir istekte bulunmak üzere AJAX isteğinde bulunmak için kullanılır:
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}`
}
Not
Hem istek üst bilgisinde hem de form yükünde sahtecilik engelleme belirteci sağlandığında, yalnızca üst bilgideki belirteç doğrulanır.
Minimal API'lerle sahteciliğin önlenmesi
Minimal APIs dahil edilen filtrelerin (ValidateAntiForgeryToken, AutoValidateAntiforgeryToken, IgnoreAntiforgeryToken) kullanımını desteklemez, ancak bir IAntiforgery isteği doğrulamak için gerekli API'leri sağlar.
Aşağıdaki örnek, kötü amaçlı yazılımdan koruma belirtecini doğrulayan bir filtre oluşturur:
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);
});
}
}
Filtre daha sonra bir uç noktaya uygulanabilir:
app.MapPost("api/upload", (IFormFile name) => Results.Accepted())
.RequireAuthorization()
.ValidateAntiforgery();
Windows kimlik doğrulaması ve sahtecilik önleyici tanımlama bilgileri
Windows Kimlik Doğrulaması kullanılırken, uygulama uç noktalarının tanımlama bilgileriyle aynı şekilde CSRF saldırılarına karşı korunması gerekir. Tarayıcı, kimlik doğrulama bağlamını sunucuya örtük olarak gönderir ve uç noktaların CSRF saldırılarına karşı korunması gerekir.
Sahtecilik önlemeyi genişletme
IAntiforgeryAdditionalDataProvider türü, geliştiricilerin her belirteçte ek verileri gidip getirerek anti-CSRF sisteminin davranışını genişletmesine olanak tanır. Bir GetAdditionalData alan belirteci her oluşturulduğunda yöntemi çağrılır ve döndürülen değer oluşturulan belirtecin içine eklenir. Uygulayıcı bir zaman damgası, bir nonce veya başka bir değer döndürebilir ve daha sonra, token doğrulandığında bu veriyi doğrulamak için ValidateAdditionalData çağırabilir. İstemcinin kullanıcı adı oluşturulan belirteçlere zaten eklenmiş olduğundan bu bilgileri eklemenize gerek yoktur. Belirteç ek veriler içeriyorsa ancak yapılandırılmamışsa IAntiForgeryAdditionalDataProvider , ek veriler doğrulanmaz.
Ek kaynaklar
Siteler arası istek sahteciliği (XSRF veya CSRF olarak da bilinir), kötü amaçlı bir web uygulamasının istemci tarayıcısı ile bu tarayıcıya güvenen bir web uygulaması arasındaki etkileşimi etkilediği web'de barındırılan uygulamalara yönelik bir saldırıdır. Bu saldırılar mümkündür çünkü web tarayıcıları bir web sitesine her istekle birlikte bazı kimlik doğrulama belirteçleri türlerini otomatik olarak gönderir. Saldırı, kullanıcının daha önce kimliği doğrulanmış oturumundan yararlandığından, bu açıklardan yararlanma biçimi tek tıklamayla saldırı veya oturum sürme olarak da bilinir.
CSRF saldırısı örneği:
Bir kullanıcı form kimlik doğrulamasını kullanarak
www.good-banking-site.example.comsitesine oturum açar. Sunucu kullanıcının kimliğini doğrular ve kimlik doğrulaması cookieiçeren bir yanıt gönderir. Site, geçerli bir kimlik doğrulaması cookieile aldığı tüm isteklere güvendiği için saldırıya açık durumdadır.Kullanıcı kötü amaçlı bir siteyi ziyaret etti.
www.bad-crook-site.example.comKötü amaçlı site,
www.bad-crook-site.example.comaşağıdaki örneğe benzer bir HTML formu içerir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.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>Formun
actionkötü amaçlı siteye değil, güvenlik açığı bulunan siteye gönderildiğini fark edin. Bu, CSRF'nin "siteler arası" bölümüdür.Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı cookie için kimlik doğrulamasını
www.good-banking-site.example.comotomatik olarak içerir.İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır
www.good-banking-site.example.comve kimliği doğrulanmış bir kullanıcının gerçekleştirmesine izin verilen tüm eylemleri gerçekleştirebilir.
Kullanıcının formu göndermek için düğmeyi seçtiği senaryoya ek olarak, kötü amaçlı site şunları yapabilir:
- Formu otomatik olarak gönderen bir betik çalıştırın.
- Form gönderimini AJAX isteği olarak gönderin.
- CSS kullanarak formu gizleyin.
Bu alternatif senaryolar, başlangıçta kötü amaçlı siteyi ziyaret etmekten başka kullanıcıdan herhangi bir eylem veya giriş gerektirmez.
HTTPS kullanmak CSRF saldırısını engellemez. Kötü amaçlı site, güvenli olmayan bir istek gönderebildiği kadar kolay bir şekilde https://www.good-banking-site.example.com/ isteği de gönderebilir.
Bazı saldırılar GET isteklerine yanıt veren uç noktaları hedefler ve bu durumda eylemi gerçekleştirmek için bir görüntü etiketi kullanılabilir. Bu saldırı biçimi, görüntülere izin veren ancak JavaScript'i engelleyen forum sitelerinde yaygındır. Değişkenlerin veya kaynakların değiştirildiği GET isteklerinde durumu değiştiren uygulamalar kötü amaçlı saldırılara karşı savunmasızdır. Durumu değiştiren GET istekleri güvenli değildir. Get isteğinde hiçbir zaman durumu değiştirmemek en iyi yöntemdir.
Kimlik doğrulaması için tanımlama bilgileri kullanan web uygulamalarına CSRF saldırıları mümkündür çünkü:
- Tarayıcılar, web uygulaması tarafından verilen çerezleri depolar.
- Depolanan tanımlama bilgileri, kimliği doğrulanmış kullanıcılar için oturum tanımlama bilgilerini içerir.
- Tarayıcılar, bir etki alanıyla ilişkili tüm tanımlama bilgilerini, uygulama isteğinin tarayıcıda nasıl oluşturulduğundan bağımsız olarak her istekte web uygulamasına gönderir.
Ancak CSRF saldırıları, tanımlama bilgilerini kötüye kullanmakla sınırlı değildir. Örneğin, Temel ve Özet kimlik doğrulaması da savunmasızdır. Kullanıcı Temel veya Özet kimlik doğrulamasıyla oturum açtığında, oturum bitene kadar tarayıcı kimlik bilgilerini otomatik olarak gönderir.
Bu bağlamda oturum, kullanıcının kimliğinin doğrulandığı istemci tarafı oturumuna başvurur. Sunucu tarafı oturumlarıyla veya ASP.NET Core oturum ara yazılımıyla ilgisizdir.
Kullanıcılar, önlemler alarak CSRF güvenlik açıklarına karşı koruma sağlayabilir:
- Web uygulamalarını kullanmayı bitirdiğinizde oturumunu kapatın.
- Tarayıcı tanımlama bilgilerini düzenli aralıklarla temizleyin.
Ancak CSRF güvenlik açıkları, son kullanıcıyla değil, temel olarak web uygulamasıyla ilgili bir sorundur.
Kimlik doğrulamasının temelleri
Cookietabanlı kimlik doğrulaması, popüler bir kimlik doğrulaması biçimidir. Özellikle Tek Sayfalı Uygulamalar (SPA' lar) için belirteç tabanlı kimlik doğrulama sistemlerinin popülerliği artmaktadır.
Cookietabanlı kimlik doğrulaması
Kullanıcı kullanıcı adı ve parolasını kullanarak kimlik doğrulaması yaptığı zaman, kimlik doğrulaması ve yetkilendirme için kullanılabilecek bir kimlik doğrulama bileti içeren bir belirteç verilir. Belirteç, istemcinin yaptığı her istekle gönderilen bir cookie olarak depolanır. Bu cookie oluşturma ve doğrulama işlemi, cookie kimlik doğrulama ara yazılımı tarafından gerçekleştirilir. Arayazılım, bir kullanıcı kimliğini şifrelenmiş bir olarak seri hale getirmektedir. Sonraki isteklerde ara yazılım cookie'yi doğrular, kimliği yeniden oluşturur ve kimliği HttpContext.User özelliğine atar.
Belirteç tabanlı kimlik doğrulaması
Bir kullanıcının kimliği doğrulandığında, ona bir belirteç verilir (bir sahteciliğe karşı koruma belirteci değil). Belirteç, haklar biçiminde kullanıcı bilgilerini veya uygulamada tutulan kullanıcı durumuna işaret eden bir referans belirteci içerir. Kullanıcı kimlik doğrulaması gerektiren bir kaynağa erişmeye çalıştığında belirteç, Taşıyıcı belirteci biçiminde ek yetkilendirme üst bilgisi ile uygulamaya gönderilir. Bu yaklaşım uygulamayı durumsuz hale getirir. Sonraki her istekte, belirteç sunucu tarafı doğrulama isteğine geçirilir. Bu belirteç şifrelenmez; kodlanır. Sunucuda belirtecin kodu bilgilerine erişmek için çözülmektedir. Sonraki isteklerde belirteci göndermek için belirteci tarayıcının yerel depolama alanında depolayın. Belirteç tarayıcının yerel depolama alanında depolanıyorsa CSRF güvenlik açığı konusunda endişelenmeyin. CSRF, belirtecin bir cookie içinde depolandığı durumlarda sorundur. Daha fazla bilgi için GitHub konusuna bakın: SPA kodu örneği iki çerez ekler.
Bir alan adında barındırılan birden fazla uygulama
Paylaşılan barındırma ortamları oturum ele geçirme, oturum açma CSRF'leri ve diğer saldırılara karşı savunmasızdır.
ve example1.contoso.net farklı konaklar olsa example2.contoso.net da, etki alanı altındaki *.contoso.net konaklar arasında örtük bir güven ilişkisi vardır. Bu örtük güven ilişkisi, potansiyel olarak güvenilmeyen konakların birbirlerinin çerezlerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP çerezleri için geçerli olmayabilir).
Aynı etki alanında barındırılan uygulamalar arasındaki güvenilir tanımlama bilgilerini istismar eden saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her bir uygulama kendi alanında barındırıldığında, istismar edilecek örtük bir güven ilişkisi yoktur.
ASP.NET Core'da Sahtecilikle Mücadele
Uyarı
ASP.NET Core, ASP.NET Core Veri Koruması kullanarak kötü amaçlı yazılımdan koruma uygular. Veri koruma yığını bir sunucu grubunda çalışacak şekilde yapılandırılmalıdır. Daha fazla bilgi için bkz . Veri korumasını yapılandırma.
Aşağıdaki API'lerden biri çağrıldığında, sahtecilik karşıtı ara yazılım bağımlılık enjeksiyonu konteynerine eklenir:
FormTagHelper, HTML form öğelerine sahtecilik önleme belirteçleri ekler. Bir dosyada Razor aşağıdaki işaretleme otomatik olarak kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form method="post">
<!-- ... -->
</form>
Benzer şekilde, IHtmlHelper.BeginForm formun yöntemi GET değilse varsayılan olarak antiforgery belirteçleri oluşturur.
HTML form öğeleri için otomatik sahte belirteç oluşturma işlemi, <form> etiketi method="post" özniteliğini içerdiğinde ve aşağıdakilerden biri doğru olduğunda gerçekleşir:
- Eylem özniteliği boş (
action=""). - Eylem özniteliği sağlanmadı (
<form method="post">).
HTML form öğeleri için kimlik doğrulama belirteçlerinin otomatik oluşturulması devre dışı bırakılabilir.
asp-antiforgeryözniteliği ile antiforgery belirteçlerini açıkça devre dışı bırakın.<form method="post" asp-antiforgery="false"> <!-- ... --> </form>Form öğesi Etiket Yardımcısı ! geri çevirme simgesi kullanılarak Etiket Yardımcıları'nı geri çevirmiş olur:
<!form method="post"> <!-- ... --> </!form>FormTagHelperöğesini görünümden kaldırın. Bir görünümdenFormTagHelperkaldırılabilir, bunun için Razor görünümüne aşağıdaki yönerge eklenmelidir.@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Not
Razor Sayfalar XSRF/CSRF'den otomatik olarak korunur. Daha fazla bilgi için bkz . XSRF/CSRF ve Razor Sayfalar.
CSRF saldırılarına karşı savunmaya yönelik en yaygın yaklaşım, Eşitleyici Belirteci Deseni'ni (STP) kullanmaktır. Kullanıcı form verilerini içeren bir sayfa istediğinde STP kullanılır:
- Sunucu, geçerli kullanıcının kimliğiyle ilişkilendirilmiş bir belirteci istemciye gönderir.
- İstemci doğrulama için belirteci sunucuya geri gönderir.
- Sunucu kimliği doğrulanmış kullanıcının kimliğiyle eşleşmeyen bir belirteç alırsa istek reddedilir.
Belirteç benzersizdir ve öngörülemez. Belirteç, bir dizi isteğin düzgün sıralanmasını sağlamak için de kullanılabilir (örneğin, istek sırasının sağlanması: sayfa 1 > sayfa 2 > sayfa 3). ASP.NET Core MVC ve Razor Pages şablonlarındaki tüm formlar, sahtecilik önleyici jetonlar oluşturur. Aşağıdaki görünüm örnekleri çifti, kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form asp-action="Index" asp-controller="Home" method="post">
<!-- ... -->
</form>
@using (Html.BeginForm("Index", "Home"))
{
<!-- ... -->
}
HTML yardımcısı <form> ile Etiket Yardımcıları kullanmadan bir @Html.AntiForgeryToken öğesine açıkça bir sahtecilik karşıtı belirteç ekleyin.
<form asp-action="Index" asp-controller="Home" method="post">
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Önceki durumların her birinde, ASP.NET Core aşağıdaki örneğe benzer bir gizli form alanı ekler:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core, kötü amaçlı yazılımdan koruma belirteçleriyle çalışmak için üç filtre içerir:
AddControllers ile antiforgery
ÇağrıAddControllersasla sahteciliğe karşı koruma belirteçlerini etkinleştirmez. AddControllersWithViews yerleşik sahtecilik önleme belirteci desteğine sahip olmak için çağrılmalıdır.
Birden çok tarayıcı sekmesi ve Eşitleyici Belirteci Deseni
Eşitleyici Belirteci Deseni ile yalnızca en son yüklenen sayfa geçerli bir kötü amaçlı yazılım önleme belirteci içerir. Birden çok sekme kullanmak sorunlu olabilir. Örneğin, bir kullanıcı birden çok sekme açarsa:
- Yalnızca en son yüklenen sekme geçerli bir kötü amaçlı yazılımdan koruma belirteci içerir.
- Daha önce yüklenen sekmelerden yapılan istekler bir hatayla başarısız olur:
Antiforgery token validation failed. The antiforgery cookie token and request token do not match
Bu bir sorun oluşturuyorsa alternatif CSRF koruma desenlerini göz önünde bulundurun.
AntiforgeryOptions ile sahtecilik önleyiciyi yapılandırın
Uygulamanın AntiforgeryOptions dosyasını Program içinde özelleştirin.
builder.Services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Aşağıdaki tabloda gösterildiği gibi cookie sınıfının özelliklerini kullanarak, sahteciliği önleme CookieBuilder özelliklerini ayarlayın.
| Seçenek | Açıklama |
|---|---|
| Cookie | Sahtecilik karşıtı tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler. |
| FormFieldName | Antiforgery sistemi tarafından görünümlerde sahteciliğe karşı belirteçleri oluşturmak için kullanılan gizli form alanının adı. |
| HeaderName | Sahtecilik önleme sistemi tarafından kullanılan başlığın adı. ise null, sistem yalnızca form verilerini dikkate alır. |
| SuppressXFrameOptionsHeader | Başlığın oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Başlık varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. Varsayılan değer false olarak ayarlanır. |
Bazı tarayıcılar güvenli olmayan uç noktaların 'güvenli' bayrağı olan tanımlama bilgilerini ayarlamasına veya 'güvenli' bayrağı ayarlanmış tanımlama bilgilerinin üzerine yazmasına izin vermez (daha fazla bilgi için bkz. Güvenli olmayan kaynaklardan 'güvenli' tanımlama bilgilerinin değiştirilmesini kaldırma). Güvenli ve güvensiz uç noktaların karıştırılması uygulamalarda yaygın bir senaryo olduğundan, ASP.NET Core, sahtecilik karşıtı gibi bazı tanımlama bilgilerindeki güvenli ilke kısıtlamasını, cookie'nin cookie'sini SecurePolicy olarak ayarlayarak gevşetir. Kötü amaçlı bir kullanıcı bir sahteciliğe karşı cookiekoruma çalsa bile, genellikle bir form alanı (daha yaygın) veya ayrı bir istek üst bilgisi (daha az yaygın) ve kimlik doğrulaması cookiearacılığıyla gönderilen sahteciliğe karşı koruma belirtecini de çalmalıdır. Kimlik doğrulaması veya yetkilendirmeyle ilgili tanımlama bilgileri, CookieSecurePolicy.None'dan daha güçlü bir ilke kullanır.
İsteğe bağlı olarak, uygulamanın cookie dosyasında aşağıdaki Development özellik ayarıyla, yalnızca HTTPS üzerinden Güvenli Yuva Katmanı (SSL) kullanarak ortamlarda olmayan ortamlardaki kötü amaçlı AntiforgeryOptions.CookieProgram yazılımdan korumanın güvenliğini sağlayabilirsiniz:
if (!builder.Environment.IsDevelopment())
{
builder.Services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
Daha fazla bilgi için bkz. CookieAuthenticationOptions.
IAntiforgery ile antiforgery belirteçleri oluşturma
IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar.
IAntiforgery, Program.cs kullanılarak WebApplication.Services istenebilir. Aşağıdaki örnek, uygulamanın giriş sayfasındaki ara yazılımı kullanarak bir kötü amaçlı yazılımdan koruma belirteci oluşturur ve bunu yanıtta cookieolarak gönderir:
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);
});
Yukarıdaki örnek, cookie adlı bir XSRF-TOKEN ayarlar. İstemci bunu cookie okuyabilir ve değerini AJAX isteklerine başlık olarak ekleyebilir. Örneğin, Angular, varsayılan olarak bir adı okuyan yerleşik XSRF koruması cookie içerirXSRF-TOKEN.
Antiforgery doğrulaması gerektirir
ValidateAntiForgeryToken eylem filtresi tek bir eyleme, denetleyiciye veya genel olarak uygulanabilir. bu filtrenin uygulandığı eylemlere yapılan istekler, istek geçerli bir kötü amaçlı yazılımdan koruma belirteci içermediği sürece engellenir:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index()
{
// ...
return RedirectToAction();
}
Bu ValidateAntiForgeryToken özniteliği, HTTP GET istekleri dahil olmak üzere, işaretlediği eylem yöntemleri için isteklerde bir belirteç gerektirir. Uygulamanın kontrolörlerinde ValidateAntiForgeryToken özniteliği uygulanmışsa, bu öznitelik IgnoreAntiforgeryToken özniteliği ile geçersiz kılınabilir.
Güvenli olmayan HTTP yöntemleri için sahtecilik karşıtı jetonları otomatik olarak doğrula.
AutoValidateAntiforgeryTokenValidateAntiForgeryToken çalışır:
- GET
- BAŞ
- SEÇENEKLER
- TRACE
API dışı senaryolar için geniş kapsamlı olarak kullanılmasını AutoValidateAntiforgeryToken öneririz. Bu öznitelik POST eylemlerinin varsayılan olarak korunmasını sağlar. Bunun alternatifi, tek tek eylem yöntemlerine uygulanmadığı sürece, varsayılan olarak sahtekarlık önleme belirteçlerini yoksaymaktır. Post eylem yönteminin yanlışlıkla korumasız bırakılması ve uygulamayı CSRF saldırılarına karşı savunmasız bırakma olasılığı bu senaryoda daha yüksektir. Tüm POST'ler, kötü amaçlı yazılımdan koruma belirtecini göndermelidir.
API'ler belirtecin parçası olmayancookie kısmını göndermek için otomatik bir mekanizmaya sahip değildir. Uygulama büyük olasılıkla istemci kodu uygulamasına bağlıdır. Aşağıda bazı örnekler gösterilmiştir:
Sınıf düzeyi örneği:
[AutoValidateAntiforgeryToken]
public class HomeController : Controller
Genel örnek:
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
Genel veya denetleyici sahtecilik önleme özniteliklerini geçersiz kılma
IgnoreAntiforgeryToken filtresi, belirli bir eylem (veya denetleyici) için bir antiforgery belirteci gereksinimini ortadan kaldırmak için kullanılır. Uygulandığında, bu filtre, daha yüksek bir düzeyde (ValidateAntiForgeryToken veya AutoValidateAntiforgeryToken filtrelerinde) belirtilen genel veya denetleyici düzeyindeki filtreleri geçersiz kılar.
[IgnoreAntiforgeryToken]
public IActionResult IndexOverride()
{
// ...
return RedirectToAction();
}
Kimlik doğrulaması sonrasında belirteçleri yenileme
Belirteçler, kullanıcının kimliği doğrulandıktan sonra kullanıcıyı bir görünüme veya Razor Sayfalar sayfasına yönlendirerek yenilenmelidir.
JavaScript, AJAX ve SPA'lar
Geleneksel HTML tabanlı uygulamalarda, kötü amaçlı yazılımdan koruma belirteçleri gizli form alanları kullanılarak sunucuya geçirilir. Modern JavaScript tabanlı uygulamalarda ve SPA'larda program aracılığıyla birçok istek yapılır. Bu AJAX istekleri, belirteci göndermek için başka teknikler (istek üst bilgileri veya tanımlama bilgileri gibi) kullanabilir.
Kimlik doğrulama belirteçlerini depolamak ve sunucuda API isteklerini kimliğini doğrulamak için tanımlama bilgileri kullanılıyorsa, CSRF olası bir sorundur. Belirteci depolamak için yerel depolama kullanılıyorsa, yerel depolamadaki değerler her istekle birlikte sunucuya otomatik olarak gönderilmediğinden CSRF güvenlik açığı giderilebilir. İstemcide kötü amaçlı yazılımdan koruma belirtecini depolamak için yerel depolamayı kullanmak ve belirteci istek üst bilgisi olarak göndermek önerilen bir yaklaşımdır.
JavaScript
JavaScript'i görünümlerle kullanarak belirteç, görünümün içinden bir hizmet kullanılarak oluşturulabilir. IAntiforgery hizmetini görünüme aktar ve GetAndStoreTokens çağır:
@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>
}
Yukarıdaki örnekte, AJAX POST üst bilgisinin gizli alan değerini okumak için JavaScript kullanılır.
Bu yaklaşım, sunucudan tanımlama bilgileri ayarlama veya bunları istemciden okuma gereksinimini ortadan kaldırır. Ancak, hizmeti IAntiforgery enjekte etmek mümkün olmadığında, JavaScript, genellikle same-origin olan sunucuya yapılan ek bir istekten alınan tanımlama bilgilerindeki belirtece de erişebilir ve belirtecin değeriyle bir başlık oluşturmak için cookie'nin içeriğini kullanabilir.
Betiğin belirteç adlı X-XSRF-TOKEN üst bilgiye sahip bir istek gönderdiğini varsayarsak, sahtecilik önleme hizmetini X-XSRF-TOKEN üst bilgiyi arayacak şekilde yapılandırın.
builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
Aşağıdaki örnek, istek belirtecini JavaScript tarafından okunabilir bir cookie öğeye yazacak korumalı bir uç nokta ekler.
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();
Aşağıdaki örnekte JavaScript, belirteci almak ve uygun üst bilgiyle başka bir istekte bulunmak üzere AJAX isteğinde bulunmak için kullanılır:
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}`
}
Windows kimlik doğrulaması ve sahtecilik önleyici tanımlama bilgileri
Windows Kimlik Doğrulaması kullanılırken, uygulama uç noktalarının tanımlama bilgileriyle aynı şekilde CSRF saldırılarına karşı korunması gerekir. Tarayıcı, kimlik doğrulama bağlamını örtük olarak sunucuya gönderir ve bu nedenle uç noktaların CSRF saldırılarına karşı korunması gerekir.
Sahtecilik önlemeyi genişletme
IAntiforgeryAdditionalDataProvider türü, geliştiricilerin her belirteçte ek verileri gidip getirerek anti-CSRF sisteminin davranışını genişletmesine olanak tanır. Bir GetAdditionalData alan belirteci her oluşturulduğunda yöntemi çağrılır ve döndürülen değer oluşturulan belirtecin içine eklenir. Uygulayıcı bir zaman damgası, bir nonce veya başka bir değer döndürebilir ve daha sonra, token doğrulandığında bu veriyi doğrulamak için ValidateAdditionalData çağırabilir. İstemcinin kullanıcı adı oluşturulan belirteçlere zaten eklenmiş olduğundan bu bilgileri eklemenize gerek yoktur. Belirteç ek veriler içeriyorsa ancak yapılandırılmamışsa IAntiForgeryAdditionalDataProvider , ek veriler doğrulanmaz.
Ek kaynaklar
Siteler arası istek sahteciliği (XSRF veya CSRF olarak da bilinir), kötü amaçlı bir web uygulamasının istemci tarayıcısı ile bu tarayıcıya güvenen bir web uygulaması arasındaki etkileşimi etkilediği web'de barındırılan uygulamalara yönelik bir saldırıdır. Bu saldırılar mümkündür çünkü web tarayıcıları bir web sitesine her istekle birlikte bazı kimlik doğrulama belirteçleri türlerini otomatik olarak gönderir. Saldırı, kullanıcının daha önce kimliği doğrulanmış oturumundan yararlandığından, bu açıklardan yararlanma biçimi tek tıklamayla saldırı veya oturum sürme olarak da bilinir.
CSRF saldırısı örneği:
Bir kullanıcı form kimlik doğrulamasını kullanarak
www.good-banking-site.example.comsitesine oturum açar. Sunucu kullanıcının kimliğini doğrular ve kimlik doğrulaması cookieiçeren bir yanıt gönderir. Site, geçerli bir kimlik doğrulaması cookieile aldığı tüm isteklere güvendiği için saldırıya açık durumdadır.Kullanıcı kötü amaçlı bir siteyi ziyaret etti.
www.bad-crook-site.example.comKötü amaçlı site,
www.bad-crook-site.example.comaşağıdaki örneğe benzer bir HTML formu içerir:<h1>Congratulations! You're a Winner!</h1> <form action="https://www.good-banking-site.example.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>Formun
actionkötü amaçlı siteye değil, güvenlik açığı bulunan siteye gönderildiğini fark edin. Bu, CSRF'nin "siteler arası" bölümüdür.Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı cookie için kimlik doğrulamasını
www.good-banking-site.example.comotomatik olarak içerir.İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır
www.good-banking-site.example.comve kimliği doğrulanmış bir kullanıcının gerçekleştirmesine izin verilen tüm eylemleri gerçekleştirebilir.
Kullanıcının formu göndermek için düğmeyi seçtiği senaryoya ek olarak, kötü amaçlı site şunları yapabilir:
- Formu otomatik olarak gönderen bir betik çalıştırın.
- Form gönderimini AJAX isteği olarak gönderin.
- CSS kullanarak formu gizleyin.
Bu alternatif senaryolar, başlangıçta kötü amaçlı siteyi ziyaret etmekten başka kullanıcıdan herhangi bir eylem veya giriş gerektirmez.
HTTPS kullanmak CSRF saldırısını engellemez. Kötü amaçlı site, güvenli olmayan bir istek gönderebildiği kadar kolay bir şekilde https://www.good-banking-site.example.com/ isteği de gönderebilir.
Bazı saldırılar GET isteklerine yanıt veren uç noktaları hedefler ve bu durumda eylemi gerçekleştirmek için bir görüntü etiketi kullanılabilir. Bu saldırı biçimi, görüntülere izin veren ancak JavaScript'i engelleyen forum sitelerinde yaygındır. Değişkenlerin veya kaynakların değiştirildiği GET isteklerinde durumu değiştiren uygulamalar kötü amaçlı saldırılara karşı savunmasızdır. Durumu değiştiren GET istekleri güvenli değildir. Get isteğinde hiçbir zaman durumu değiştirmemek en iyi yöntemdir.
Kimlik doğrulaması için tanımlama bilgileri kullanan web uygulamalarına CSRF saldırıları mümkündür çünkü:
- Tarayıcılar, web uygulaması tarafından verilen çerezleri depolar.
- Depolanan tanımlama bilgileri, kimliği doğrulanmış kullanıcılar için oturum tanımlama bilgilerini içerir.
- Tarayıcılar, bir etki alanıyla ilişkili tüm tanımlama bilgilerini, uygulama isteğinin tarayıcıda nasıl oluşturulduğundan bağımsız olarak her istekte web uygulamasına gönderir.
Ancak CSRF saldırıları, tanımlama bilgilerini kötüye kullanmakla sınırlı değildir. Örneğin, Temel ve Özet kimlik doğrulaması da savunmasızdır. Kullanıcı Temel veya Özet kimlik doğrulamasıyla oturum açtığında, oturum bitene kadar tarayıcı kimlik bilgilerini otomatik olarak gönderir.
Bu bağlamda oturum, kullanıcının kimliğinin doğrulandığı istemci tarafı oturumuna başvurur. Sunucu tarafı oturumlarıyla veya ASP.NET Core oturum ara yazılımıyla ilgisizdir.
Kullanıcılar, önlemler alarak CSRF güvenlik açıklarına karşı koruma sağlayabilir:
- Web uygulamalarını kullanmayı bitirdiğinizde oturumunu kapatın.
- Tarayıcı tanımlama bilgilerini düzenli aralıklarla temizleyin.
Ancak CSRF güvenlik açıkları, son kullanıcıyla değil, temel olarak web uygulamasıyla ilgili bir sorundur.
Kimlik doğrulamasının temelleri
Cookietabanlı kimlik doğrulaması, popüler bir kimlik doğrulaması biçimidir. Özellikle Tek Sayfalı Uygulamalar (SPA' lar) için belirteç tabanlı kimlik doğrulama sistemlerinin popülerliği artmaktadır.
Cookietabanlı kimlik doğrulaması
Kullanıcı kullanıcı adı ve parolasını kullanarak kimlik doğrulaması yaptığı zaman, kimlik doğrulaması ve yetkilendirme için kullanılabilecek bir kimlik doğrulama bileti içeren bir belirteç verilir. Belirteç, istemcinin yaptığı her istekle gönderilen bir cookie olarak depolanır. Bu cookie öğesinin oluşturulması ve doğrulanması, cookie kimlik doğrulama ara katmanı tarafından gerçekleştirilir. Arayazılım, bir kullanıcı kimliğini şifrelenmiş bir olarak seri hale getirmektedir. Sonraki isteklerde ara yazılım cookie'yi doğrular, kimliği yeniden oluşturur ve kimliği HttpContext.User özelliğine atar.
Belirteç tabanlı kimlik doğrulaması
Bir kullanıcının kimliği doğrulandığında, ona bir belirteç verilir (bir sahteciliğe karşı koruma belirteci değil). Belirteç, haklar biçiminde kullanıcı bilgilerini veya uygulamada tutulan kullanıcı durumuna işaret eden bir referans belirteci içerir. Kullanıcı kimlik doğrulaması gerektiren bir kaynağa erişmeye çalıştığında belirteç, Taşıyıcı belirteci biçiminde ek yetkilendirme üst bilgisi ile uygulamaya gönderilir. Bu yaklaşım uygulamayı durumsuz hale getirir. Sonraki her istekte, belirteç sunucu tarafı doğrulama isteğine geçirilir. Bu belirteç şifrelenmez; kodlanır. Sunucuda belirtecin kodu bilgilerine erişmek için çözülmektedir. Sonraki isteklerde belirteci göndermek için belirteci tarayıcının yerel depolama alanında depolayın. Belirteç tarayıcının yerel depolama alanında depolanıyorsa CSRF güvenlik açığı konusunda endişelenmeyin. CSRF, belirtecin bir cookie içinde depolandığı durumlarda sorundur. Daha fazla bilgi için GitHub konusuna bakın: SPA kodu örneği iki çerez ekler.
Bir alan adında barındırılan birden fazla uygulama
Paylaşılan barındırma ortamları oturum ele geçirme, oturum açma CSRF'leri ve diğer saldırılara karşı savunmasızdır.
ve example1.contoso.net farklı konaklar olsa example2.contoso.net da, etki alanı altındaki *.contoso.net konaklar arasında örtük bir güven ilişkisi vardır. Bu örtük güven ilişkisi, potansiyel olarak güvenilmeyen konakların birbirlerinin çerezlerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP çerezleri için geçerli olmayabilir).
Aynı etki alanında barındırılan uygulamalar arasındaki güvenilir tanımlama bilgilerini istismar eden saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her bir uygulama kendi alanında barındırıldığında, istismar edilecek örtük bir güven ilişkisi yoktur.
ASP.NET Core antiforgery yapılandırması
Uyarı
ASP.NET Core, ASP.NET Core Veri Koruması kullanarak kötü amaçlı yazılımdan koruma uygular. Veri koruma yığını bir sunucu grubunda çalışacak şekilde yapılandırılmalıdır. Daha fazla bilgi için bkz . Veri korumasını yapılandırma.
Aşağıdaki API'lerden biri çağrıldığında, sahtecilik karşıtı ara yazılım bağımlılık enjeksiyonu konteynerine eklenir:
ASP.NET Core 2.0 veya sonraki sürümlerinde, FormTagHelper HTML form öğelerine sahtecilik karşıtı belirteçler ekler. Bir dosyada Razor aşağıdaki işaretleme otomatik olarak kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form method="post">
...
</form>
Benzer şekilde, IHtmlHelper.BeginForm formun yöntemi GET değilse varsayılan olarak antiforgery belirteçleri oluşturur.
HTML form öğeleri için otomatik sahte belirteç oluşturma işlemi, <form> etiketi method="post" özniteliğini içerdiğinde ve aşağıdakilerden biri doğru olduğunda gerçekleşir:
- Eylem özniteliği boş (
action=""). - Eylem özniteliği sağlanmadı (
<form method="post">).
HTML form öğeleri için kimlik doğrulama belirteçlerinin otomatik oluşturulması devre dışı bırakılabilir.
asp-antiforgeryözniteliği ile antiforgery belirteçlerini açıkça devre dışı bırakın.<form method="post" asp-antiforgery="false"> ... </form>Form öğesi Etiket Yardımcısı ! geri çevirme simgesi kullanılarak Etiket Yardımcıları'nı geri çevirmiş olur:
<!form method="post"> ... </!form>FormTagHelperöğesini görünümden kaldırın. Bir görünümdenFormTagHelperkaldırılabilir, bunun için Razor görünümüne aşağıdaki yönerge eklenmelidir.@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Not
Razor Sayfalar XSRF/CSRF'den otomatik olarak korunur. Daha fazla bilgi için bkz . XSRF/CSRF ve Razor Sayfalar.
CSRF saldırılarına karşı savunmaya yönelik en yaygın yaklaşım, Eşitleyici Belirteci Deseni'ni (STP) kullanmaktır. Kullanıcı form verilerini içeren bir sayfa istediğinde STP kullanılır:
- Sunucu, geçerli kullanıcının kimliğiyle ilişkilendirilmiş bir belirteci istemciye gönderir.
- İstemci doğrulama için belirteci sunucuya geri gönderir.
- Sunucu kimliği doğrulanmış kullanıcının kimliğiyle eşleşmeyen bir belirteç alırsa istek reddedilir.
Belirteç benzersizdir ve öngörülemez. Belirteç, bir dizi isteğin düzgün sıralanmasını sağlamak için de kullanılabilir (örneğin, istek sırasının sağlanması: sayfa 1 > sayfa 2 > sayfa 3). ASP.NET Core MVC ve Razor Pages şablonlarındaki tüm formlar, sahtecilik önleyici jetonlar oluşturur. Aşağıdaki görünüm örnekleri çifti, kötü amaçlı yazılımdan koruma belirteçleri oluşturur:
<form asp-controller="Todo" asp-action="Create" method="post">
...
</form>
@using (Html.BeginForm("Create", "Todo"))
{
...
}
HTML yardımcısı <form> ile Etiket Yardımcıları kullanmadan bir @Html.AntiForgeryToken öğesine açıkça bir sahtecilik karşıtı belirteç ekleyin.
<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
Önceki durumların her birinde, ASP.NET Core aşağıdaki örneğe benzer bir gizli form alanı ekler:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core, kötü amaçlı yazılımdan koruma belirteçleriyle çalışmak için üç filtre içerir:
Sahtecilik önleme seçenekleri
AntiforgeryOptions'yi Startup.ConfigureServices uygulamasında özelleştirin.
services.AddAntiforgery(options =>
{
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
Aşağıdaki tabloda gösterildiği gibi cookie sınıfının özelliklerini kullanarak, sahteciliği önleme CookieBuilder özelliklerini ayarlayın.
| Seçenek | Açıklama |
|---|---|
| Cookie | Sahtecilik karşıtı tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler. |
| FormFieldName | Antiforgery sistemi tarafından görünümlerde sahteciliğe karşı belirteçleri oluşturmak için kullanılan gizli form alanının adı. |
| HeaderName | Sahtecilik önleme sistemi tarafından kullanılan başlığın adı. ise null, sistem yalnızca form verilerini dikkate alır. |
| SuppressXFrameOptionsHeader | Başlığın oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Başlık varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. Varsayılan değer false olarak ayarlanır. |
Bazı tarayıcılar güvenli olmayan uç noktaların 'güvenli' bayrağı olan tanımlama bilgilerini ayarlamasına veya 'güvenli' bayrağı ayarlanmış tanımlama bilgilerinin üzerine yazmasına izin vermez (daha fazla bilgi için bkz. Güvenli olmayan kaynaklardan 'güvenli' tanımlama bilgilerinin değiştirilmesini kaldırma). Güvenli ve güvensiz uç noktaların karıştırılması uygulamalarda yaygın bir senaryo olduğundan, ASP.NET Core, sahtecilik karşıtı gibi bazı tanımlama bilgilerindeki güvenli ilke kısıtlamasını, cookie'nin cookie'sini SecurePolicy olarak ayarlayarak gevşetir. Kötü amaçlı bir kullanıcı bir sahteciliğe karşı cookiekoruma çalsa bile, genellikle bir form alanı (daha yaygın) veya ayrı bir istek üst bilgisi (daha az yaygın) ve kimlik doğrulaması cookiearacılığıyla gönderilen sahteciliğe karşı koruma belirtecini de çalmalıdır. Kimlik doğrulaması veya yetkilendirmeyle ilgili tanımlama bilgileri, CookieSecurePolicy.None'dan daha güçlü bir ilke kullanır.
İsteğe bağlı olarak, ortama özel olmayan cookie ortamlarda sahtecilik önlemeyi güvence altına almak için yalnızca HTTPS üzerinden Secure Sockets Layer (SSL) kullanarak, uygulamanın Development sınıfında aşağıdaki AntiforgeryOptions.Cookie özellik ayarını yapabilirsiniz:
public class Startup
{
public Startup(IConfiguration configuration, IHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
public IConfiguration Configuration { get; }
public IHostEnvironment Environment { get; }
public void ConfigureServices(IServiceCollection services)
{
// Other services are registered here
if (!Environment.IsDevelopment())
{
services.AddAntiforgery(o =>
{
o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
});
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Request processing pipeline
}
}
Daha fazla bilgi için bkz. CookieAuthenticationOptions.
IAntiforgery kullanarak antiforgery özelliklerini yapılandırma
IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar.
IAntiforgery, Configure yönteminde Startup sınıfı ile istenebilir.
Aşağıdaki örnekte:
- Uygulamanın giriş sayfasındaki ara yazılım, bir kötü amaçlı yazılımdan koruma belirteci oluşturmak ve bunu yanıtta cookieolarak göndermek için kullanılır.
- İstek belirteci, cookie bölümünde açıklanan varsayılan Angular adlandırma kuralıyla, JavaScript tarafından okunabilir bir olarak gönderilir.
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);
});
}
Antiforgery doğrulaması gerektirir
ValidateAntiForgeryToken , tek bir eyleme, denetleyiciye veya genel olarak uygulanabilen bir eylem filtresidir. bu filtrenin uygulandığı eylemlere yapılan istekler, istek geçerli bir kötü amaçlı yazılımdan koruma belirteci içermediği sürece engellenir.
[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 });
}
Bu ValidateAntiForgeryToken özniteliği, HTTP GET istekleri dahil olmak üzere, işaretlediği eylem yöntemleri için isteklerde bir belirteç gerektirir. Uygulamanın kontrolörlerinde ValidateAntiForgeryToken özniteliği uygulanmışsa, bu öznitelik IgnoreAntiforgeryToken özniteliği ile geçersiz kılınabilir.
Not
ASP.NET Core, GET isteklerine otomatik olarak kötü amaçlı yazılımdan koruma belirteçleri eklemeyi desteklemez.
Güvenli olmayan HTTP yöntemleri için sahtecilik karşıtı jetonları otomatik olarak doğrula.
ASP.NET Core uygulamaları güvenli HTTP yöntemleri (GET, HEAD, OPTIONS ve TRACE) için antiforgery belirteçleri oluşturmaz. AutoValidateAntiforgeryTokenValidateAntiForgeryToken çalışır:
- GET
- BAŞ
- SEÇENEKLER
- TRACE
API dışı senaryolar için geniş kapsamlı olarak kullanılmasını AutoValidateAntiforgeryToken öneririz. Bu öznitelik POST eylemlerinin varsayılan olarak korunmasını sağlar. Bunun alternatifi, tek tek eylem yöntemlerine uygulanmadığı sürece, varsayılan olarak sahtekarlık önleme belirteçlerini yoksaymaktır. Post eylem yönteminin yanlışlıkla korumasız bırakılması ve uygulamayı CSRF saldırılarına karşı savunmasız bırakma olasılığı bu senaryoda daha yüksektir. Tüm POST'ler, kötü amaçlı yazılımdan koruma belirtecini göndermelidir.
API'ler belirtecin parçası olmayancookie kısmını göndermek için otomatik bir mekanizmaya sahip değildir. Uygulama büyük olasılıkla istemci kodu uygulamasına bağlıdır. Aşağıda bazı örnekler gösterilmiştir:
Sınıf düzeyi örneği:
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
Genel örnek:
services.AddControllersWithViews(options =>
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
Genel veya denetleyici sahtecilik önleme özniteliklerini geçersiz kılma
IgnoreAntiforgeryToken filtresi, belirli bir eylem (veya denetleyici) için bir antiforgery belirteci gereksinimini ortadan kaldırmak için kullanılır. Uygulandığında, bu filtre, daha yüksek bir düzeyde (ValidateAntiForgeryToken veya AutoValidateAntiforgeryToken filtrelerinde) belirtilen genel veya denetleyici düzeyindeki filtreleri geçersiz kılar.
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
{
// no antiforgery token required
}
}
Kimlik doğrulaması sonrasında belirteçleri yenileme
Belirteçler, kullanıcının kimliği doğrulandıktan sonra kullanıcıyı bir görünüme veya Razor Sayfalar sayfasına yönlendirerek yenilenmelidir.
JavaScript, AJAX ve SPA'lar
Geleneksel HTML tabanlı uygulamalarda, kötü amaçlı yazılımdan koruma belirteçleri gizli form alanları kullanılarak sunucuya geçirilir. Modern JavaScript tabanlı uygulamalarda ve SPA'larda program aracılığıyla birçok istek yapılır. Bu AJAX istekleri, belirteci göndermek için başka teknikler (istek üst bilgileri veya tanımlama bilgileri gibi) kullanabilir.
Kimlik doğrulama belirteçlerini depolamak ve sunucuda API isteklerini kimliğini doğrulamak için tanımlama bilgileri kullanılıyorsa, CSRF olası bir sorundur. Belirteci depolamak için yerel depolama kullanılıyorsa, yerel depolamadaki değerler her istekle birlikte sunucuya otomatik olarak gönderilmediğinden CSRF güvenlik açığı giderilebilir. İstemcide kötü amaçlı yazılımdan koruma belirtecini depolamak için yerel depolamayı kullanmak ve belirteci istek üst bilgisi olarak göndermek önerilen bir yaklaşımdır.
JavaScript
JavaScript'i görünümlerle kullanarak belirteç, görünümün içinden bir hizmet kullanılarak oluşturulabilir. IAntiforgery hizmetini görünüme aktar ve GetAndStoreTokens çağır:
@{
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>
Bu yaklaşım, sunucudan tanımlama bilgileri ayarlama veya bunları istemciden okuma gereksinimini ortadan kaldırır.
Yukarıdaki örnekte, AJAX POST üst bilgisinin gizli alan değerini okumak için JavaScript kullanılır.
JavaScript ayrıca çerezlerdeki belirteçlere erişebilir ve cookie'nin içeriğini kullanarak belirtecin değeriyle bir başlık oluşturabilir.
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
Betiğin belirteci X-CSRF-TOKEN adlı bir üst bilgide göndermeyi istediği varsayıldığında, sahtekarlık önleme hizmetini, X-CSRF-TOKEN üst bilgisini arayacak şekilde yapılandırın.
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
Aşağıdaki örnek, uygun üst bilgiyle AJAX isteğinde bulunmak için JavaScript'i kullanır:
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, CSRF'yi ele almak için bir kural kullanır. Sunucu cookie'yi XSRF-TOKEN adıyla gönderirse, AngularJS $http servisi sunucuya bir istek gönderdiğinde cookie değerini bir üst bilgiye ekler. Bu işlem otomatiktir. İstemcinin üst bilgiyi açıkça ayarlaması gerekmez. Üst bilgi adı X-XSRF-TOKEN'dir. Sunucu bu üst bilgiyi algılamalı ve içeriğini doğrulamalıdır.
ASP.NET Core API'lerinin uygulama başlatmanızda bu kuralla çalışması için:
- Uygulamanızı, cookie adlı
XSRF-TOKENiçinde bir belirteç sağlayacak şekilde yapılandırın. - Sahtecilik önleme hizmetini, Angular'ın XSRF belirtecini göndermek amacıyla varsayılan üst bilgi adı olan
X-XSRF-TOKENadlı üst bilgiyi arayacak şekilde yapılandırın.
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");
}
Not
Hem istek üst bilgisinde hem de form yükünde sahtecilik engelleme belirteci sağlandığında, yalnızca üst bilgideki belirteç doğrulanır.
Windows kimlik doğrulaması ve sahtecilik önleyici tanımlama bilgileri
Windows Kimlik Doğrulaması kullanılırken, uygulama uç noktalarının tanımlama bilgileriyle aynı şekilde CSRF saldırılarına karşı korunması gerekir. Tarayıcı, kimlik doğrulama bağlamını örtük olarak sunucuya gönderir ve bu nedenle uç noktaların CSRF saldırılarına karşı korunması gerekir.
Sahtecilik önlemeyi genişletme
IAntiforgeryAdditionalDataProvider türü, geliştiricilerin her belirteçte ek verileri gidip getirerek anti-CSRF sisteminin davranışını genişletmesine olanak tanır. Bir GetAdditionalData alan belirteci her oluşturulduğunda yöntemi çağrılır ve döndürülen değer oluşturulan belirtecin içine eklenir. Uygulayıcı bir zaman damgası, bir nonce veya başka bir değer döndürebilir ve daha sonra, token doğrulandığında bu veriyi doğrulamak için ValidateAdditionalData çağırabilir. İstemcinin kullanıcı adı oluşturulan belirteçlere zaten eklenmiş olduğundan bu bilgileri eklemenize gerek yoktur. Belirteç ek veriler içeriyorsa ancak yapılandırılmamışsa IAntiForgeryAdditionalDataProvider , ek veriler doğrulanmaz.
Ek kaynaklar
ASP.NET Core