ASP.NET Core'da Siteler Arası İstek Sahteciliği (XSRF/CSRF) saldırılarını önleme

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:

  1. Bir kullanıcı form kimlik doğrulaması kullanarak oturum www.good-banking-site.example.com 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.

  2. Kullanıcı kötü amaçlı bir siteyi ziyaret etti. www.bad-crook-site.example.com

    Kö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://good-banking-site.com/api/account" method="post">
        <input type="hidden" name="Transaction" value="withdraw" />
        <input type="hidden" name="Amount" value="1000000" />
        <input type="submit" value="Click to collect your prize!" />
    </form>
    

    Formun action kö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.

  3. Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı www.good-banking-site.example.comiçin kimlik doğrulamasını cookie otomatik olarak içerir.

  4. İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır www.good-banking-site.example.com ve 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 https://www.good-banking-site.com/ istek gönderebildiği kadar kolay bir istek 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 bir web uygulaması tarafından verilen tanımlama bilgilerini 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ı veya ASP.NET Çekirdek Oturum Ara Yazılımı ile 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.

Bir kullanıcı kullanıcı adı ve parolasını kullanarak kimlik doğrulaması yaparken, 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. Bunun cookie oluşturulması ve doğrulanması, Kimlik Doğrulama Ara Yazılımı ile Cookie gerçekleştirilir. Ara yazılım, kullanıcı sorumlusunu şifrelenmiş cookieolarak seri hale getirmektedir. Sonraki isteklerde ara yazılım, öğesini doğrular cookie, sorumluyu yeniden oluşturur ve sorumluyu özelliğine HttpContext.User 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ç, talep biçiminde kullanıcı bilgilerini veya uygulamayı uygulamada tutulan kullanıcı durumuna işaret eden bir başvuru 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ı durum bilgisi olmayan 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. Belirteci tarayıcı yerel depolama alanına yerleştirmek ve almak ve taşıyıcı belirteç 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 içinde depolandığı durumlarda bir cookiesorundur. Daha fazla bilgi için bkz. GitHub sorunu SPA kodu örneği iki tanımlama bilgisi ekler.

Bir etki alanında barındırılan birden çok 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 example2.contoso.net farklı konaklar olsa example1.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, güvenilmeyen olabilecek konakların birbirlerinin tanımlama bilgilerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP tanımlama bilgileri için geçerli olmayabilir).

Aynı etki alanında barındırılan uygulamalar arasında güvenilen tanımlama bilgilerinde yararlanan saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her uygulama kendi etki alanında barındırıldığında, yararlanacak örtük cookie bir güven ilişkisi yoktur.

ASP.NET Core'da antiforgery

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 içinde Program.csçağrıldığında bağımlılık ekleme kapsayıcısına kötü amaçlı yazılımdan koruma yazılımı eklenir:

Daha fazla bilgi için bkz . Minimal API'lerle sahteciliğe karşı koruma.

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.

ETIKET özniteliğini içerdiğinde method="post" ve aşağıdakilerden biri doğru olduğunda <form> HTML form öğeleri için otomatik olarak sahte belirteç oluşturma işlemi gerçekleşir:

  • Eylem özniteliği boş (action="" ).
  • Eylem özniteliği sağlanmadı (<form method="post">).

HTML form öğeleri için otomatik sahte belirteç oluşturma devre dışı bırakılabilir:

  • Antiforgery belirteçlerini şu öznitelikle asp-antiforgery 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. FormTagHelper görünümüne aşağıdaki yönerge Razor eklenerek bir görünümden kaldırılabilir:

    @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:

  1. Sunucu, geçerli kullanıcınınkiyle identity ilişkilendirilmiş bir belirteci istemciye gönderir.
  2. İstemci doğrulama için belirteci sunucuya geri gönderir.
  3. Sunucu kimliği doğrulanmış kullanıcınınkiyle identityeş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, sahte belirteçler 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ıyla @Html.AntiForgeryTokenEtiket Yardımcıları kullanmadan bir <form> öğeye açıkça bir kötü amaçlı yazılımdan koruma belirteci 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:

Ile antiforgery AddControllers

ÇağrıAddControllers, sahteciliğe karşı koruma belirteçlerini etkinleştirmez. AddControllersWithViews yerleşik kötü amaçlı yazılımdan koruma 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.

ile kötü amaçlı yazılımdan korumayı yapılandırma AntiforgeryOptions

uygulamasında özelleştirin AntiforgeryOptions Program.cs:

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 sınıfının özelliklerini kullanarak kötü amaçlı yazılımdan Cookie koruma özelliklerini CookieBuilder ayarlayın.

Seçenek Açıklama
Cookie Kötü amaçlı yazılımdan koruma tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler.
FormFieldName Antiforgery sistemi tarafından görünümlerde sahte belirteçleri işlemek için kullanılan gizli form alanının adı.
HeaderName Kötü amaçlı yazılımdan koruma sistemi tarafından kullanılan üst bilginin adı. ise null, sistem yalnızca form verilerini dikkate alır.
SuppressXFrameOptionsHeader Üst bilginin oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Üst bilgi varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. varsayılan değeridir false.

Daha fazla bilgi için bkz. CookieAuthenticationOptions.

ile antiforgery belirteçleri oluşturma IAntiforgery

IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar. IAntiforgerykullanılarak WebApplication.ServicesistenebilirProgram.cs. Aşağıdaki örnek, uygulama home sayfasından ara yazılımı kullanarak bir kötü amaçlı yazılımdan koruma belirteci oluşturur ve bunu yanıtta olarak cookiegö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 adlı XSRF-TOKENbir cookie ayarlar. İstemci bunu cookie okuyabilir ve değerini AJAX isteklerine eklenmiş bir üst bilgi olarak sağlayabilir. Örneğin Angular, varsayılan olarak bir cookie adı XSRF-TOKEN okuyan yerleşik XSRF koruması içerir.

Antiforgery doğrulaması gerektir

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

özniteliği, ValidateAntiForgeryToken HTTP GET istekleri dahil olmak üzere işaretlediğinden eylem yöntemlerine yönelik istekler için bir belirteç gerektirir. Özniteliği uygulamanın ValidateAntiForgeryToken denetleyicilerine uygulanırsa, özniteliğiyle IgnoreAntiforgeryToken geçersiz kılınabilir.

Yalnızca güvenli olmayan HTTP yöntemleri için sahte belirteçleri otomatik olarak doğrulama

AutoValidateAntiforgeryToken özniteliğini geniş kapsamlı bir şekilde uygulamak ValidateAntiForgeryToken ve özniteliklerle IgnoreAntiforgeryToken geçersiz kılması yerine kullanılabilir. Bu öznitelik, aşağıdaki HTTP yöntemleri kullanılarak yapılan istekler için belirteç gerektirmemesi dışında özniteliğiyle aynı şekilde ValidateAntiForgeryToken çalışır:

  • GET
  • HEAD
  • OPTIONS
  • 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 ValidateAntiForgeryToken , varsayılan olarak kötü amaçlı yazılımdan koruma 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 kötü amaçlı yazılımdan koruma ö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 (genel olarak veya denetleyicide) belirtilen filtreleri geçersiz kılar ve AutoValidateAntiforgeryToken filtrelerValidateAntiForgeryToken.

[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 üst bilgileri veya tanımlama bilgileri gibi diğer teknikleri kullanabilir.

Kimlik doğrulama belirteçlerini depolamak ve SUNUCUDA API isteklerinin 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 Hizmeti görünüme ekleme ve çağrısıGetAndStoreTokens:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery

@{
    ViewData["Title"] = "JavaScript";

    var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}

<input id="RequestVerificationToken" type="hidden" value="@requestToken" />

<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>

@section Scripts {
<script>
    document.addEventListener("DOMContentLoaded", () => {
        const resultElement = document.getElementById("result");

        document.getElementById("button").addEventListener("click", async () => {

            const response = await fetch("@Url.Action("FetchEndpoint")", {
                method: "POST",
                headers: {
                    RequestVerificationToken:
                        document.getElementById("RequestVerificationToken").value
                }
            });

            if (response.ok) {
                resultElement.innerText = await response.text();
            } else {
                resultElement.innerText = `Request Failed: ${response.status}`
            }
        });
    });
</script>
}

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 eklemek IAntiforgery mümkün değildir, tanımlama bilgilerindeki belirteçlere erişmek için JavaScript kullanın:

  • Sunucuya same-originyönelik ek bir istekte bulunan belirteçlere genellikle erişin.
  • Belirtecin cookiedeğeriyle bir üst bilgi oluşturmak için 'nin içeriğini kullanın.

Betiğin belirteci adlı X-XSRF-TOKENbir istek üst bilgisinde gönderdiğini varsayarsak, kötü amaçlı yazılımdan koruma hizmetini üst bilgiyi aramak için X-XSRF-TOKEN yapılandırın:

builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

Aşağıdaki örnek, istek belirtecini JavaScript tarafından okunabilir cookiebir öğeye 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 sahte belirteç sağlandığında, yalnızca üst bilgideki belirteç doğrulanır.

Minimum API'lerle antiforgery

AddAntiforgery'yi arayın ve UseAntiforgery(IApplicationBuilder) di'ye kötü amaçlı yazılımdan koruma hizmetlerini kaydetmek için. 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ı:

  • İstek işlem hattının yürütülmesini rest kısa devre yapmaz.
  • Geçerli isteğin HttpContext.Features içindeki IAntiforgeryValidationFeature değerini ayarlar.

Antiforgery belirteci yalnızca aşağıdaki durumlarda doğrulanır:

  • Uç nokta, IAntiforgeryMetadata uygulayan meta verileri içerir.RequiresValidation=true
  • Uç noktayla ilişkili HTTP yöntemi ilgili bir HTTP yöntemidir. İlgili yöntemler TRACE, OPTIONS, HEAD ve GET dışındaki tüm HTTP yöntemleridir .
  • İstek geçerli bir uç noktayla ilişkilendirildi.

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 en düşük API'ler, sahte belirteç doğrulaması gerektirir.

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:

  • /todo geçerli bir antiforgery belirteci gerektirir.
  • /todo2çağrıldığından geçerli bir antiforgery belirteci DisableAntiforgery gerektirmez.
app.MapPost("/todo", ([FromForm] Todo todo) => Results.Ok(todo));

app.MapPost("/todo2", ([FromForm] Todo todo) => Results.Ok(todo))
                                                .DisableAntiforgery();

Gönderi:

  • /todo kötü amaçlı yazılımdan koruma belirteci geçerli olduğundan uç nokta tarafından / oluşturulan formdan başarılı olur.
  • /todo antiforgery dahil edilmediğinden tarafından oluşturulan /SkipToken formdan başarısız oluyor.
  • /todo2 kötü amaçlı yazılımdan koruma gerekli olmadığından uç nokta tarafından /DisableAntiforgery 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:

  • Geliştirme ortamında bir özel durum oluşturulur.
  • Üretim ortamında bir ileti günlüğe kaydedilir.

Windows kimlik doğrulaması ve kötü amaçlı yazılımdan koruma 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.

Antiforgeriyi genişletme

Türü IAntiforgeryAdditionalDataProvider , geliştiricilerin her belirteçte ek verileri yuvarlayarak CSRF'yi önleme 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ı, nonce veya başka bir değer döndürebilir ve ardından belirteç doğrulandığında bu verileri doğrulamak için çağrısı ValidateAdditionalData yapabilir. İ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:

  1. Bir kullanıcı form kimlik doğrulaması kullanarak oturum www.good-banking-site.example.com 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.

  2. Kullanıcı kötü amaçlı bir siteyi ziyaret etti. www.bad-crook-site.example.com

    Kö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://good-banking-site.com/api/account" method="post">
        <input type="hidden" name="Transaction" value="withdraw" />
        <input type="hidden" name="Amount" value="1000000" />
        <input type="submit" value="Click to collect your prize!" />
    </form>
    

    Formun action kö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.

  3. Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı www.good-banking-site.example.comiçin kimlik doğrulamasını cookie otomatik olarak içerir.

  4. İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır www.good-banking-site.example.com ve 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 https://www.good-banking-site.com/ istek gönderebileceği kadar kolay bir istek 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 bir web uygulaması tarafından verilen tanımlama bilgilerini 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ı veya ASP.NET Çekirdek Oturum Ara Yazılımı ile 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.

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. Bunun cookie oluşturulması ve doğrulanması, Kimlik Doğrulama Ara Yazılımı tarafından Cookie gerçekleştirilir. Ara yazılım, kullanıcı sorumlusunu şifrelenmiş cookieolarak seri hale getirmektedir. Sonraki isteklerde ara yazılım, öğesini doğrular cookie, sorumluyu yeniden oluşturur ve sorumluyu özelliğine HttpContext.User 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ç, talep biçiminde kullanıcı bilgilerini veya uygulamayı uygulamada tutulan kullanıcı durumuna işaret eden bir başvuru 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ı durum bilgisi olmayan 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. Belirteci tarayıcı yerel depolama alanına yerleştirmek ve almak ve taşıyıcı belirteç 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 içinde depolandığı durumlarda bir cookiesorundur. Daha fazla bilgi için bkz. GitHub sorunu SPA kodu örneği iki tanımlama bilgisi ekler.

Bir etki alanında barındırılan birden çok 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 example2.contoso.net farklı konaklar olsa example1.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, güvenilmeyen olabilecek konakların birbirlerinin tanımlama bilgilerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP tanımlama bilgileri için geçerli olmayabilir).

Aynı etki alanında barındırılan uygulamalar arasında güvenilen tanımlama bilgilerinde yararlanan saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her uygulama kendi etki alanında barındırıldığında, yararlanacak örtük cookie bir güven ilişkisi yoktur.

ASP.NET Core'da antiforgery

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 içinde Program.csçağrıldığında bağımlılık ekleme kapsayıcısına kötü amaçlı yazılımdan koruma yazılımı 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.

ETIKET özniteliğini içerdiğinde method="post" ve aşağıdakilerden biri doğru olduğunda <form> HTML form öğeleri için otomatik olarak sahte belirteç oluşturma işlemi gerçekleşir:

  • Eylem özniteliği boş (action="" ).
  • Eylem özniteliği sağlanmadı (<form method="post">).

HTML form öğeleri için otomatik sahte belirteç oluşturma devre dışı bırakılabilir:

  • Antiforgery belirteçlerini şu öznitelikle asp-antiforgery 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. FormTagHelper görünümüne aşağıdaki yönerge Razor eklenerek bir görünümden kaldırılabilir:

    @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:

  1. Sunucu, geçerli kullanıcınınkiyle identity ilişkilendirilmiş bir belirteci istemciye gönderir.
  2. İstemci doğrulama için belirteci sunucuya geri gönderir.
  3. Sunucu kimliği doğrulanmış kullanıcınınkiyle identityeş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, sahte belirteçler 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ıyla @Html.AntiForgeryTokenEtiket Yardımcıları kullanmadan bir <form> öğeye açıkça bir kötü amaçlı yazılımdan koruma belirteci 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:

Ile antiforgery AddControllers

ÇağrıAddControllers, sahteciliğe karşı koruma belirteçlerini etkinleştirmez. AddControllersWithViews yerleşik kötü amaçlı yazılımdan koruma 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.

ile kötü amaçlı yazılımdan korumayı yapılandırma AntiforgeryOptions

uygulamasında özelleştirin AntiforgeryOptions Program.cs:

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 sınıfının özelliklerini kullanarak kötü amaçlı yazılımdan Cookie koruma özelliklerini CookieBuilder ayarlayın.

Seçenek Açıklama
Cookie Kötü amaçlı yazılımdan koruma tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler.
FormFieldName Antiforgery sistemi tarafından görünümlerde sahte belirteçleri işlemek için kullanılan gizli form alanının adı.
HeaderName Kötü amaçlı yazılımdan koruma sistemi tarafından kullanılan üst bilginin adı. ise null, sistem yalnızca form verilerini dikkate alır.
SuppressXFrameOptionsHeader Üst bilginin oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Üst bilgi varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. varsayılan değeridir false.

Daha fazla bilgi için bkz. CookieAuthenticationOptions.

ile antiforgery belirteçleri oluşturma IAntiforgery

IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar. IAntiforgerykullanılarak WebApplication.ServicesistenebilirProgram.cs. Aşağıdaki örnek, uygulama home sayfasından ara yazılımı kullanarak bir kötü amaçlı yazılımdan koruma belirteci oluşturur ve bunu yanıtta olarak cookiegö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 adlı XSRF-TOKENbir cookie ayarlar. İstemci bunu cookie okuyabilir ve değerini AJAX isteklerine eklenmiş bir üst bilgi olarak sağlayabilir. Örneğin Angular, varsayılan olarak bir cookie adı XSRF-TOKEN okuyan yerleşik XSRF koruması içerir.

Antiforgery doğrulaması gerektir

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

özniteliği, ValidateAntiForgeryToken HTTP GET istekleri dahil olmak üzere işaretlediğinden eylem yöntemlerine yönelik istekler için bir belirteç gerektirir. Özniteliği uygulamanın ValidateAntiForgeryToken denetleyicilerine uygulanırsa, özniteliğiyle IgnoreAntiforgeryToken geçersiz kılınabilir.

Yalnızca güvenli olmayan HTTP yöntemleri için sahte belirteçleri otomatik olarak doğrulama

AutoValidateAntiforgeryToken özniteliğini geniş kapsamlı bir şekilde uygulamak ValidateAntiForgeryToken ve özniteliklerle IgnoreAntiforgeryToken geçersiz kılması yerine kullanılabilir. Bu öznitelik, aşağıdaki HTTP yöntemleri kullanılarak yapılan istekler için belirteç gerektirmemesi dışında özniteliğiyle aynı şekilde ValidateAntiForgeryToken çalışır:

  • GET
  • HEAD
  • OPTIONS
  • 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 ValidateAntiForgeryToken , varsayılan olarak kötü amaçlı yazılımdan koruma 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 kötü amaçlı yazılımdan koruma ö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 (genel olarak veya denetleyicide) belirtilen filtreleri geçersiz kılar ve AutoValidateAntiforgeryToken filtrelerValidateAntiForgeryToken.

[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 isteklerinin 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 Hizmeti görünüme ekleme ve çağrısıGetAndStoreTokens:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery

@{
    ViewData["Title"] = "JavaScript";

    var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}

<input id="RequestVerificationToken" type="hidden" value="@requestToken" />

<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>

@section Scripts {
<script>
    document.addEventListener("DOMContentLoaded", () => {
        const resultElement = document.getElementById("result");

        document.getElementById("button").addEventListener("click", async () => {

            const response = await fetch("@Url.Action("FetchEndpoint")", {
                method: "POST",
                headers: {
                    RequestVerificationToken:
                        document.getElementById("RequestVerificationToken").value
                }
            });

            if (response.ok) {
                resultElement.innerText = await response.text();
            } else {
                resultElement.innerText = `Request Failed: ${response.status}`
            }
        });
    });
</script>
}

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 eklemek IAntiforgery mümkün değildir, tanımlama bilgilerindeki belirteçlere erişmek için JavaScript kullanın:

  • Sunucuya same-originyönelik ek bir istekte bulunan belirteçlere genellikle erişin.
  • Belirtecin cookiedeğeriyle bir üst bilgi oluşturmak için 'nin içeriğini kullanın.

Betiğin belirteci adlı X-XSRF-TOKENbir istek üst bilgisinde gönderdiğini varsayarsak, kötü amaçlı yazılımdan koruma hizmetini üst bilgiyi aramak için X-XSRF-TOKEN yapılandırın:

builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

Aşağıdaki örnek, istek belirtecini JavaScript tarafından okunabilir cookiebir öğeye 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 sahte belirteç sağlandığında, yalnızca üst bilgideki belirteç doğrulanır.

Minimum API'lerle antiforgery

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 kötü amaçlı yazılımdan koruma 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.

Antiforgeriyi genişletme

Türü IAntiforgeryAdditionalDataProvider , geliştiricilerin her belirteçte ek verileri yuvarlayarak CSRF'yi önleme 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ı, nonce veya başka bir değer döndürebilir ve ardından belirteç doğrulandığında bu verileri doğrulamak için çağrısı ValidateAdditionalData yapabilir. İ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:

  1. Bir kullanıcı form kimlik doğrulaması kullanarak oturum www.good-banking-site.example.com 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.

  2. Kullanıcı kötü amaçlı bir siteyi ziyaret etti. www.bad-crook-site.example.com

    Kö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://good-banking-site.com/api/account" method="post">
        <input type="hidden" name="Transaction" value="withdraw" />
        <input type="hidden" name="Amount" value="1000000" />
        <input type="submit" value="Click to collect your prize!" />
    </form>
    

    Formun action kö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.

  3. Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı www.good-banking-site.example.comiçin kimlik doğrulamasını cookie otomatik olarak içerir.

  4. İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır www.good-banking-site.example.com ve 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 https://www.good-banking-site.com/ istek gönderebileceği kadar kolay bir istek 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 bir web uygulaması tarafından verilen tanımlama bilgilerini 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ı veya ASP.NET Çekirdek Oturum Ara Yazılımı ile 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.

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. Bunun cookie oluşturulması ve doğrulanması, Kimlik Doğrulama Ara Yazılımı tarafından Cookie gerçekleştirilir. Ara yazılım, kullanıcı sorumlusunu şifrelenmiş cookieolarak seri hale getirmektedir. Sonraki isteklerde ara yazılım, öğesini doğrular cookie, sorumluyu yeniden oluşturur ve sorumluyu özelliğine HttpContext.User 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ç, talep biçiminde kullanıcı bilgilerini veya uygulamayı uygulamada tutulan kullanıcı durumuna işaret eden bir başvuru 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ı durum bilgisi olmayan 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 içinde depolandığı durumlarda bir cookiesorundur. Daha fazla bilgi için bkz. GitHub sorunu SPA kodu örneği iki tanımlama bilgisi ekler.

Bir etki alanında barındırılan birden çok 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 example2.contoso.net farklı konaklar olsa example1.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, güvenilmeyen olabilecek konakların birbirlerinin tanımlama bilgilerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP tanımlama bilgileri için geçerli olmayabilir).

Aynı etki alanında barındırılan uygulamalar arasında güvenilen tanımlama bilgilerinde yararlanan saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her uygulama kendi etki alanında barındırıldığında, yararlanacak örtük cookie bir güven ilişkisi yoktur.

ASP.NET Core'da antiforgery

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 içinde Program.csçağrıldığında bağımlılık ekleme kapsayıcısına kötü amaçlı yazılımdan koruma yazılımı 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.

ETIKET özniteliğini içerdiğinde method="post" ve aşağıdakilerden biri doğru olduğunda <form> HTML form öğeleri için otomatik olarak sahte belirteç oluşturma işlemi gerçekleşir:

  • Eylem özniteliği boş (action="" ).
  • Eylem özniteliği sağlanmadı (<form method="post">).

HTML form öğeleri için otomatik sahte belirteç oluşturma devre dışı bırakılabilir:

  • Antiforgery belirteçlerini şu öznitelikle asp-antiforgery 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. FormTagHelper görünümüne aşağıdaki yönerge Razor eklenerek bir görünümden kaldırılabilir:

    @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:

  1. Sunucu, geçerli kullanıcınınkiyle identity ilişkilendirilmiş bir belirteci istemciye gönderir.
  2. İstemci doğrulama için belirteci sunucuya geri gönderir.
  3. Sunucu kimliği doğrulanmış kullanıcınınkiyle identityeş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, sahte belirteçler 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ıyla @Html.AntiForgeryTokenEtiket Yardımcıları kullanmadan bir <form> öğeye açıkça bir kötü amaçlı yazılımdan koruma belirteci 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ıAddControllers, sahteciliğe karşı koruma belirteçlerini etkinleştirmez. AddControllersWithViews yerleşik kötü amaçlı yazılımdan koruma 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.

ile kötü amaçlı yazılımdan korumayı yapılandırma AntiforgeryOptions

uygulamasında özelleştirin AntiforgeryOptions Program.cs:

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 sınıfının özelliklerini kullanarak kötü amaçlı yazılımdan Cookie koruma özelliklerini CookieBuilder ayarlayın.

Seçenek Açıklama
Cookie Kötü amaçlı yazılımdan koruma tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler.
FormFieldName Antiforgery sistemi tarafından görünümlerde sahte belirteçleri işlemek için kullanılan gizli form alanının adı.
HeaderName Kötü amaçlı yazılımdan koruma sistemi tarafından kullanılan üst bilginin adı. ise null, sistem yalnızca form verilerini dikkate alır.
SuppressXFrameOptionsHeader Üst bilginin oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Üst bilgi varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. varsayılan değeridir false.

Daha fazla bilgi için bkz. CookieAuthenticationOptions.

ile antiforgery belirteçleri oluşturma IAntiforgery

IAntiforgery , kötü amaçlı yazılımdan koruma özelliklerini yapılandırmak için API'yi sağlar. IAntiforgerykullanılarak WebApplication.ServicesistenebilirProgram.cs. Aşağıdaki örnek, uygulama home sayfasından ara yazılımı kullanarak bir kötü amaçlı yazılımdan koruma belirteci oluşturur ve bunu yanıtta olarak cookiegö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 adlı XSRF-TOKENbir cookie ayarlar. İstemci bunu cookie okuyabilir ve değerini AJAX isteklerine eklenmiş bir üst bilgi olarak sağlayabilir. Örneğin Angular, varsayılan olarak bir cookie adı XSRF-TOKEN okuyan yerleşik XSRF koruması içerir.

Antiforgery doğrulaması gerektir

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

özniteliği, ValidateAntiForgeryToken HTTP GET istekleri dahil olmak üzere işaretlediğinden eylem yöntemlerine yönelik istekler için bir belirteç gerektirir. Özniteliği uygulamanın ValidateAntiForgeryToken denetleyicilerine uygulanırsa, özniteliğiyle IgnoreAntiforgeryToken geçersiz kılınabilir.

Yalnızca güvenli olmayan HTTP yöntemleri için sahte belirteçleri otomatik olarak doğrulama

AutoValidateAntiforgeryToken özniteliğini geniş kapsamlı bir şekilde uygulamak ValidateAntiForgeryToken ve özniteliklerle IgnoreAntiforgeryToken geçersiz kılması yerine kullanılabilir. Bu öznitelik, aşağıdaki HTTP yöntemleri kullanılarak yapılan istekler için belirteç gerektirmemesi dışında özniteliğiyle aynı şekilde ValidateAntiForgeryToken çalışır:

  • GET
  • HEAD
  • OPTIONS
  • 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 ValidateAntiForgeryToken , varsayılan olarak kötü amaçlı yazılımdan koruma 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 kötü amaçlı yazılımdan koruma ö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 (genel olarak veya denetleyicide) belirtilen filtreleri geçersiz kılar ve AutoValidateAntiforgeryToken filtrelerValidateAntiForgeryToken.

[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 isteklerinin 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 Hizmeti görünüme ekleme ve çağrısıGetAndStoreTokens:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery

@{
    ViewData["Title"] = "JavaScript";

    var requestToken = Antiforgery.GetAndStoreTokens(Context).RequestToken;
}

<input id="RequestVerificationToken" type="hidden" value="@requestToken" />

<button id="button" class="btn btn-primary">Submit with Token</button>
<div id="result" class="mt-2"></div>

@section Scripts {
<script>
    document.addEventListener("DOMContentLoaded", () => {
        const resultElement = document.getElementById("result");

        document.getElementById("button").addEventListener("click", async () => {

            const response = await fetch("@Url.Action("FetchEndpoint")", {
                method: "POST",
                headers: {
                    RequestVerificationToken:
                        document.getElementById("RequestVerificationToken").value
                }
            });

            if (response.ok) {
                resultElement.innerText = await response.text();
            } else {
                resultElement.innerText = `Request Failed: ${response.status}`
            }
        });
    });
</script>
}

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 eklemek mümkün olmadığında JavaScript, sunucuya IAntiforgery ek bir istekten (genellikle same-origin) alınan tanımlama bilgilerindeki belirtece de erişebilir ve belirtecin değeriyle üst bilgi oluşturmak için 'nin içeriğini kullanabilir cookie.

Betiğin belirteci adlı X-XSRF-TOKENbir istek üst bilgisinde gönderdiğini varsayarsak, kötü amaçlı yazılımdan koruma hizmetini üst bilgiyi aramak için X-XSRF-TOKEN yapılandırın:

builder.Services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");

Aşağıdaki örnek, istek belirtecini JavaScript tarafından okunabilir cookiebir öğ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 kötü amaçlı yazılımdan koruma 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.

Antiforgeriyi genişletme

Türü IAntiforgeryAdditionalDataProvider , geliştiricilerin her belirteçte ek verileri yuvarlayarak CSRF'yi önleme 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ı, nonce veya başka bir değer döndürebilir ve ardından belirteç doğrulandığında bu verileri doğrulamak için çağrısı ValidateAdditionalData yapabilir. İ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:

  1. Bir kullanıcı form kimlik doğrulaması kullanarak oturum www.good-banking-site.example.com 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.

  2. Kullanıcı kötü amaçlı bir siteyi ziyaret etti. www.bad-crook-site.example.com

    Kö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://good-banking-site.com/api/account" method="post">
        <input type="hidden" name="Transaction" value="withdraw" />
        <input type="hidden" name="Amount" value="1000000" />
        <input type="submit" value="Click to collect your prize!" />
    </form>
    

    Formun action kö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.

  3. Kullanıcı gönder düğmesini seçer. Tarayıcı isteği yapar ve istenen etki alanı www.good-banking-site.example.comiçin kimlik doğrulamasını cookie otomatik olarak içerir.

  4. İstek, kullanıcının kimlik doğrulama bağlamıyla sunucuda çalışır www.good-banking-site.example.com ve 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 https://www.good-banking-site.com/ istek gönderebileceği kadar kolay bir istek 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 bir web uygulaması tarafından verilen tanımlama bilgilerini 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ı veya ASP.NET Çekirdek Oturum Ara Yazılımı ile 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.

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. Bunun cookie oluşturulması ve doğrulanması, Kimlik Doğrulama Ara Yazılımı tarafından Cookie gerçekleştirilir. Ara yazılım, kullanıcı sorumlusunu şifrelenmiş cookieolarak seri hale getirmektedir. Sonraki isteklerde ara yazılım, öğesini doğrular cookie, sorumluyu yeniden oluşturur ve sorumluyu özelliğine HttpContext.User 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ç, talep biçiminde kullanıcı bilgilerini veya uygulamayı uygulamada tutulan kullanıcı durumuna işaret eden bir başvuru 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ı durum bilgisi olmayan 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 içinde depolandığı durumlarda bir cookiesorundur. Daha fazla bilgi için bkz. GitHub sorunu SPA kodu örneği iki tanımlama bilgisi ekler.

Bir etki alanında barındırılan birden çok 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 example2.contoso.net farklı konaklar olsa example1.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, güvenilmeyen olabilecek konakların birbirlerinin tanımlama bilgilerini etkilemesine olanak tanır (AJAX isteklerini yöneten aynı kaynak ilkeleri HTTP tanımlama bilgileri için geçerli olmayabilir).

Aynı etki alanında barındırılan uygulamalar arasında güvenilen tanımlama bilgilerinde yararlanan saldırılar, etki alanlarının paylaşılmamasıyla önlenebilir. Her uygulama kendi etki alanında barındırıldığında, yararlanacak örtük cookie 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 içinde Startup.ConfigureServicesçağrıldığında bağımlılık ekleme kapsayıcısına kötü amaçlı yazılımdan koruma yazılımı eklenir:

ASP.NET Core 2.0 veya sonraki sürümlerinde, FormTagHelper HTML form öğelerine sahte 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.

ETIKET özniteliğini içerdiğinde method="post" ve aşağıdakilerden biri doğru olduğunda <form> HTML form öğeleri için otomatik olarak sahte belirteç oluşturma işlemi gerçekleşir:

  • Eylem özniteliği boş (action="" ).
  • Eylem özniteliği sağlanmadı (<form method="post">).

HTML form öğeleri için otomatik sahte belirteç oluşturma devre dışı bırakılabilir:

  • Antiforgery belirteçlerini şu öznitelikle asp-antiforgery 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. FormTagHelper görünümüne aşağıdaki yönerge Razor eklenerek bir görünümden kaldırılabilir:

    @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:

  1. Sunucu, geçerli kullanıcınınkiyle identity ilişkilendirilmiş bir belirteci istemciye gönderir.
  2. İstemci doğrulama için belirteci sunucuya geri gönderir.
  3. Sunucu kimliği doğrulanmış kullanıcınınkiyle identityeş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, sahte belirteçler 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ıyla @Html.AntiForgeryTokenEtiket Yardımcıları kullanmadan bir <form> öğeye açıkça bir kötü amaçlı yazılımdan koruma belirteci 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:

Antiforgery seçenekleri

uygulamasında özelleştirin AntiforgeryOptions Startup.ConfigureServices:

services.AddAntiforgery(options => 
{
    options.FormFieldName = "AntiforgeryFieldname";
    options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
    options.SuppressXFrameOptionsHeader = false;
});

Aşağıdaki tabloda gösterildiği gibi sınıfının özelliklerini kullanarak kötü amaçlı yazılımdan Cookie koruma özelliklerini CookieBuilder ayarlayın.

Seçenek Açıklama
Cookie Kötü amaçlı yazılımdan koruma tanımlama bilgilerini oluşturmak için kullanılan ayarları belirler.
FormFieldName Antiforgery sistemi tarafından görünümlerde sahte belirteçleri işlemek için kullanılan gizli form alanının adı.
HeaderName Kötü amaçlı yazılımdan koruma sistemi tarafından kullanılan üst bilginin adı. ise null, sistem yalnızca form verilerini dikkate alır.
SuppressXFrameOptionsHeader Üst bilginin oluşturulmasının engellenip gizlenmeyeceğini X-Frame-Options belirtir. Üst bilgi varsayılan olarak "SAMEORIGIN" değeriyle oluşturulur. varsayılan değeridir false.

Daha fazla bilgi için bkz. CookieAuthenticationOptions.

IAntiforgery ile 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 sınıfının yönteminde Configure Startup istenebilir.

Aşağıdaki örnekte:

  • Uygulamanın home sayfasındaki ara yazılım, bir sahteciliğe karşı koruma belirteci oluşturmak ve yanıtta olarak cookiegöndermek için kullanılır.
  • İstek belirteci, AngularJS bölümünde açıklanan varsayılan Angular adlandırma kuralıyla JavaScript tarafından okunabilir cookie 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ı gerektir

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

özniteliği, ValidateAntiForgeryToken HTTP GET istekleri dahil olmak üzere işaretlediğinden eylem yöntemlerine yönelik istekler için bir belirteç gerektirir. Özniteliği uygulamanın ValidateAntiForgeryToken denetleyicilerine uygulanırsa, özniteliğiyle IgnoreAntiforgeryToken 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.

Yalnızca güvenli olmayan HTTP yöntemleri için sahte belirteçleri otomatik olarak doğrulama

ASP.NET Core uygulamaları güvenli HTTP yöntemleri (GET, HEAD, OPTIONS ve TRACE) için sahte belirteç oluşturmaz. AutoValidateAntiforgeryToken özniteliğini geniş kapsamlı bir şekilde uygulamak ValidateAntiForgeryToken ve özniteliklerle IgnoreAntiforgeryToken geçersiz kılması yerine kullanılabilir. Bu öznitelik, aşağıdaki HTTP yöntemleri kullanılarak yapılan istekler için belirteç gerektirmemesi dışında özniteliğiyle aynı şekilde ValidateAntiForgeryToken çalışır:

  • GET
  • HEAD
  • OPTIONS
  • 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 ValidateAntiForgeryToken , varsayılan olarak kötü amaçlı yazılımdan koruma 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 kötü amaçlı yazılımdan koruma ö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 (genel olarak veya denetleyicide) belirtilen filtreleri geçersiz kılar ve AutoValidateAntiforgeryToken filtrelerValidateAntiForgeryToken.

[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 isteklerinin 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 Hizmeti görünüme ekleme ve çağrısıGetAndStoreTokens:

@{
    ViewData["Title"] = "AJAX Demo";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(Context).RequestToken;
    }
}

<input type="hidden" id="RequestVerificationToken" 
       name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">

<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<div class="row">
    <p><input type="button" id="antiforgery" value="Antiforgery"></p>
    <script>
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (xhttp.readyState == XMLHttpRequest.DONE) {
                if (xhttp.status == 200) {
                    alert(xhttp.responseText);
                } else {
                    alert('There was an error processing the AJAX request.');
                }
            }
        };

        document.addEventListener('DOMContentLoaded', function() {
            document.getElementById("antiforgery").onclick = function () {
                xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
                xhttp.setRequestHeader("RequestVerificationToken", 
                    document.getElementById('RequestVerificationToken').value);
                xhttp.send();
            }
        });
    </script>
</div>

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 tanımlama bilgilerindeki belirteçlere erişebilir ve 'nin içeriğini kullanarak cookiebelirtecin değeriyle bir üst bilgi oluşturabilir.

context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, 
    new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });

Betiğin belirteci adlı X-CSRF-TOKENbir üst bilgide göndermeyi istediği varsayıldığında, kötü amaçlı yazılımdan koruma hizmetini üst bilgiyi aramak için X-CSRF-TOKEN 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 adlı bir cookie gönderirse, AngularJS $http hizmeti sunucuya bir istek gönderdiğinde değeri üst bilgisine eklercookie.XSRF-TOKEN Bu işlem otomatiktir. İstemcinin üst bilgiyi açıkça ayarlaması gerekmez. Üst bilgi adı şeklindedir X-XSRF-TOKEN. 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ı adlı XSRF-TOKENbir belirteç sağlayacak şekilde cookie yapılandırın.
  • Kötü amaçlı yazılımdan koruma hizmetini, Angular'ın XSRF belirtecini göndermek için varsayılan üst bilgi adı olan adlı X-XSRF-TOKENüst bilgiyi aramak üzere 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 sahte belirteç sağlandığında, yalnızca üst bilgideki belirteç doğrulanır.

Windows kimlik doğrulaması ve kötü amaçlı yazılımdan koruma 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.

Antiforgeriyi genişletme

Türü IAntiforgeryAdditionalDataProvider , geliştiricilerin her belirteçte ek verileri yuvarlayarak CSRF'yi önleme 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ı, nonce veya başka bir değer döndürebilir ve ardından belirteç doğrulandığında bu verileri doğrulamak için çağrısı ValidateAdditionalData yapabilir. İ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