اخبار، مطالب و رویدادهای مرتبط با توسعه نرم افزار رادکام

جلوگیری از حملات Cross-Site Request Forgery (XSRF/CSRF) در Asp.Net Core

جعل درخواست Cross-site (که همچنین با عناوین XSRF و CSRF نیز شناخته می شوند) حمله ایست که به برنامه هایی که روی وب سرور ها میزبانی می شوند انجام می شود، یعنی در اصل این حملات به برنامه های تحت وب انجام می گیرند، که به موجب آن، یک برنامه وب مخرب می تواند بین تعاملی که بین مرورگر مشتری(کاربر) و یک برنامه وب که به آن مرورگر اعتماد دارد، وجود دارد، تاثیر بگذارد. این حملات به این دلیل امکان پذیر هستند که مرورگر های وب برخی توکن های اعتبار سنجی را به صورت اتوماتیک به سمت هر درخواست آمده به وب سایت ارسال می کنند. این شکل از سوء استفاده همچنین با نام های حمله تک-کلیک (حمله one-click) یا Session Riding نیز خوانده می شود، به دلیل اینکه این حمله از session اعتبار سنجی شده قبلی کاربر برای اهداف خود استفاده می کند.
اگر بخواهیم مثالی از حملات CSRF ببریم:
  1.  کاربر با استفاده از تایید اعتبار سنجی مبتنی بر فرم، به وب سایت www.good-banking-site.com وارد می شود. سرور کاربر را تایید می کند و پاسخی را که شامل کوکی تایید اعتبار است، صادر می کند. حال این وب سایت مستعد آسیب پذیری در مقابل حملات است، زیرا این وب سایت به هر درخواستی که با یک کوکی تایید اعتبار معتبر دریافت می کند، اعتماد دارد.
  2. کاربر از وب سایت مخرب www.bad-crook-site.com بازدید می کند.
    این وب سایت مخرب فرم اچ تی ام ال ی مشابه کد زیر را دارد:
    <h1>Congratulations! You're a Winner!</h1>
    	<form action="http://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>	

    توجه داشته باشید که action مربوط به فرم، می تواند فرم را به وب سایت آسیب پذیر هدایت کند نه به وب سایت مخرب. این همان بخش Cross-site از CSRF است.
  3. کاربر دکمه ارسال را انتخاب می کند، مرورگر درخواست را انجام داده و به طور خودکار کوکی تایید اعتبار را برای دامنه درخواست شده www.good-banking-site.com درج می کند.
  4. درخواست کاربر در سرور وب سایت www.good-banking-site.com با هدف تایید هویت کاربر اجرا می شود و قادر است هر عملی را که کاربر معتبر مجاز به انجام دادن آن است، انجام دهد.
علاوه بر سناریویی که کاربر دکمه ارسال فرم را انتخاب می کند، سایت مخرب می تواند:
  • اسکریپتی را اجرا کند که به طور خودکار فرم را ارسال کند.
  • ارسال فرم را به عنوان یک درخواست آژاکس ارسال کند.
  • فرم را با استفاده از css پنهان کند.
این سناریوهای جایگزین به غیر از بازدید اولیه سایت مخرب، نیازی به اقدام و ورودی اطلاعات از سمت کاربر ندارند.

استفاده از HTTPS مانع از حمله های CSRF نمی شود. سایت مخرب می تواند درخواست به https://www.good-banking-site.com را به همان راحتی ارسال کند که می تواند یک درخواست ناامن ارسال کند.

برخی از این حملات نقاط انتهایی را مورد هدف قرار می دهند که به درخواست های GET پاسخ می دهند، در این صورت می توان از تگ تصویر برای انجام حمله استفاده کرد. این شکل از حمله در سایت های تالار گفتگو که مجاز به استفاده از تصاویر هستند اما JavaScript را مسدود می کنند متداول است. برنامه هایی که شرایط(state) را در درخواست های GET تغییر می دهند، در جاهایی که متغیرها یا منابع تغییر می کنند، در برابر حملات مخرب آسیب پذیر هستند. درخواست های Get که شرایط(state) را تغییر می دهند ناامن هستند. بهترین روش آن است که هرگز در یک درخواست Get، شرایط و وضعیت(state) را تغییر ندهید.

حملات CSRF ممکن است علیه برنامه هایی که از کوکی برای اعتبارسنجی استفاده می کنند، رخ دهد. به این دلیل که:
  • مرورگر ها کوکی های صادر شده توسط برنامه مبتنی بر وب را ذخیره می کنند.
  • کوکی های ذخیره شده شامل کوکی های session (نشست) برای کاربران اعتبار سنجی شده هستند.
  • مرورگرها، بدون توجه به چگونگی تولید درخواست برای برنامه در مرورگر، تمام کوکی های مرتبط با دامنه را به برنامه وب ارسال می کنند.
با این حال، حملات CSRF خود را محدود به بهره برداری کردن از کوکی ها نمی کنند. به عنوان نمونه، تایید هویت پایه(Basic and Digest authentication) نیز آسیب پذیر است، پس از اینکه کاربر با استفاده از تایید هویت پایه، وارد سیستم شد (لاگین کرد)،  مرورگر کل اطلاعات مربوط به اعتبار سنجی (اعتبار نامه) را برای درخواست دریافت شده تا پایان نشست (session) کاربر ارسال می کند.
در این مقاله، نشست(session) به نشست سمت مشتری گفته می شود که با استفاده از آن هویت کاربر احراز می شود. این نشست(session) مرتبط با جلسات سمت سرور و یا میان افزار Asp.Net Core Session نیست.

کاربران می توانند با استفاده از اقدامات احتیاطی زیر از آسیب پذیری های CSRF محافظت کنند:
  • زمانی که استفاده از نرم افزار مبتنی بر وب پایان یافت، نشست را نیز خاتمه دهید، به این معنی که از برنامه log out کنید.
  • به صورت متناوب، کوکی های مرورگر را پاک کنید.
با این حال، آسیب پذیری های CSRF، اساسا مشکلات مرتبط با برنامه های مبتنی بر وب هستند، نه کاربر نهایی استفاده کننده از آن.

مبانی و اصول تایید اعتبار

 احراز هویت (اعتبارسنجی) مبتنی بر کوکی، یک شکل رایج اعتبار سنجی است،  سیستم های تایید هویت مبتنی بر توکن نیز در حال محبوب شدن هستند، به خصوص برای برنامه های تک صفحه ای (SPA=Single Page Applications).

احراز هویت مبتنی بر کوکی

هنگامی که یک کاربر با استفاده از نام کاربری و رمز عبور، هویت خود را تأیید می کند، یک توکن (token) صادر می کند که حاوی یک بلیت تأیید اعتبار(authentication ticket) است که می تواند برای تأیید اعتبار(Authentication) و تأیید دسترسی(Authorization) مورد استفاده قرار گیرد. توکن ای که ایجاد می شود به صورت کوکی ذخیره می شود که با هر درخواست مشتری همراهی می کند و ضمیمه تمام درخواست های کاربر است. تولید و اعتبارسنجی این کوکی توسط میان افزار Cookie Authentication انجام می شود. میان افزار اشاره شده، هویت اصلی کاربر را به کوکی رمزگذاری شده سریالیزه می کند(Serialize). در درخواست های بعدی، میان افزار کوکی را اعتبارسنجی می کند، و هویت(principal) کاربر را از نو ایجاد می کند و آن را به مشخصه کاربر(User) در HttpContext تخصیص می دهد.

احراز هویت مبتنی بر توکن

 زمانی که هویت کاربر احراز می شود، یک توکن صادر می شود، این توکن شامل اطلاعات کاربر در قالب claim یا توکن مرجع است که برنامه را به وضعیت کاربر که(این وضعیت) در برنامه نگهداری می شود، متصل می کند. هنگامی که کاربر تلاش می کند که به یک منبعی که نیاز به تایید اعتبار دارد دسترسی پیدا کند، توکن به انضمام یک هدر تایید اعتبار مازاد، در قالب توکن Bearer، به سمت برنامه ارسال می شود. این کار باعث می شود که برنامه stateless(بدون وضعیت) گردد. در هر کدام از درخواست های بعدی، توکن درون خود درخواست، برای اعتبار سنجی سمت سرور ارسال می گردد. این توکن با استفاده از کلید های رمز، رمزگذاری نشده است;  بلکه در اصل encode شده است. روی سرور توکن ارسال شده decode می شود تا امکان دسترسی به اطلاعات آن فراهم گردد. برای ارسال توکن در درخواست های مرتبط بعدی، توکن در فضای محلی مرورگر ذخیره می گردد. اگر توکن در فضای محلی مرورگر ذخیره گردد، دیگر نباید نگران آسیب رسانی CSRF باشید. CSRF زمانی نگران کننده می گردد که توکن در کوکی ذخیره می شود.

برنامه های مختلف میزبانی شده در یک دامنه(حوزه)

فضاهای میزبانی مشترک در مقابل ربودن اطلاعات نشست کاربری(session hijacking)، حملات CSRF مربوط به صفحات ورود به وب سایت ها(Login CSRF) و سایر حملات آسیب پذیر هستند.
 اگر چه وب سایت های example1.contoso.net و example2.contoso.net وب سایت های متفاوت(در نتیجه، میزبان های مختلف) هستند، اما یک رابطه اعتمادی ضمنی بین میزبان های تحت دامنه *.contoso.net وجود دارد. این رابطه اعتماد ضمنی به میزبان غیر قابل اعتماد بالقوه این اجازه را می دهد تا کوکی های یکدیگر را تحت تاثیر قرار دهند.(همین سیاست های مبدا مشابه(same-origin) که حاوی درخواست های آژاکس هستند و آنها را مدیریت می کنند، لزوماً در مورد کوکی های HTTP اعمال نمی شوند).
با امتناع از به اشتراک گذاردن دامنه ها، از حمله به کوکی های مورد اعتماد بین برنامه های میزبان در همان دامنه، جلوگیری به عمل می آوریم، زمانی که هر برنامه در دامنه خود میزبانی می شود،  هیچ رابطه ای مبتنی بر اعتماد بر مبنای کوکی وجود ندارد تا مورد سوء استفاده قرار گیرد.

پیکربندی Antiforgery در Asp.NetCore

توجه:
 Asp.net Core مکانیسم ضد جعل(Antiforgery) را با استفاده از ASP.NET Core Data Protection انجام می دهد. پشته حفاظت از داده ها باید برای کار در مزرعه سرور ها(server farm) پیکربندی گردد. برای اطلاعات بیشتر به بخش پیکربندی محافظت از اطلاعات  مراجعه فرمایید.

در Asp.net Core نسخه 2 و بالاتر، کتابخانه FormTagHelper توکن های ضد جعل را به عناصر داخل فرم تزریق می کند، متن نشانه گذاری(Html) زیر در یک سند Razor، به طور خودکار توکن های ضد جعل را تولید می کند.

<form method="post">
...
</form>
به همین ترتیب، IHtmlHelper.BeginForm نیز به صورت پیش فرض، توکن های ضد جعل را، در صورتی که متد استفاده شده در تگ فرم Get، نباشد، تولید می کند.

تولید خودکار توکن ضد جعل برای عنصر Form در Html زمانی اتفاق می افتد که تگ Form شامل Method از نوع Post باشد و یا هر کدام از موارد زیر باشد:

  • مقدار ویژگی action خالی باشد(action="")
  • ویژگی action به طور کل در تگ فرم قرار نداشته باشد(<form method="post">)

تولید خودکار توکن های ضد جعل برای عنصر Form در Html زمانی غیر فعال می شود که:
  • به طور صریح با ویژگی asp-antiforgery، ایجاد توکن ضد جعل را غیر فعال کنیم:

    <form method="post" asp-antiforgery="false">
    ...
    </form>
  • با استفاده از سمبل های غیر فعال کننده Tag Helper، یعنی !، قابلیت مربوطه را در تگ Form غیر فعال کنیم:

    <!form method="post">
    ...
    </!form>		
  • FormTagHelper را از View خارج کنیم. FormTagHelper را با افزودن دایرکتیو(directive) زیر به Rasor View می توانیم حذف کنیم:

    @removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
توجه داشته باشید که:
صفحات Razor به صورت خودکار از حملات CSRF/XSRF محافظت می شوند. برای دریافت اطلاعات بیشتر به صفحه "صفحات Razor و XSRF/CSRF" مراجعه فرمایید.

متداول ترین روش برای دفاع از حملات CSRF استفاده از الگوی توکن همگام ساز(Synchronizer Token Pattern (STP)) است.STP زمانی مورد استفاده قرار می گیرد که کاربر صفحه ای را همراه با دیتای form درخواست کند:
  • سرور توکنی مرتبط با هویت کاربر فعلی را به سمت درخواست کننده ارسال می کند.
  • درخواست کننده توکن را برای تصدیق به سمت سرور باز پس می فرستد.
  • اگر سرور توکنی دریافت کند که با هویت کاربر اعتبار سنجی شده، مطابقت نداشته باشد، درخواست را رد می کند.
توکن همیشه یکتا و غیر قابل پیش بینی است، از توکن همچنین می توان برای کسب اطمینان از توالی درست یک سری از درخواست ها بهره جست(برای مثال اطمینان از توالی درخواست های: صفحه 1 - صفحه 2 - صفحه 3). تمامی form ها در قالب های Asp.net Core Mvc و صفحات Razor، توکن های ضد جعل را تولید می کنند.
مثال های زیر توکن های ضد جعل را تولید می کنند:

<form asp-controller="Manage" asp-action="ChangePassword" method="post">
...
</form>

@using (Html.BeginForm("ChangePassword", "Manage"))
{
...
}
با اضافه کردن صریح توکن ضد جعل به تگ Form، بدون استفاده از TagHelper ها و با کمک HTML Helper زیر:
@Html.AntiForgeryToken

<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
در هر یک از موارد قبلی که اشاره شد، Asp.Net Core یک فیلد پنهان به شکل زیر به Form اضافه می کند:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">

گزینه های متغیر ضد جعل

گزینه های مرتبط به سیستم ضد جعل را می توان از طریق startup و بخش Startup.ConfigureServices پیکربندی کرد:
services.AddAntiforgery(options => 
{
	// Set Cookie properties using CookieBuilder properties†.
	options.FormFieldName = "AntiforgeryFieldname";
	options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
	options.SuppressXFrameOptionsHeader = false;
});
با استفاده از خاصیت های موجود در کلاس CookieBuilder، می توان  خصوصیت های کوکی مربوط به سیستم ضد جعل را تنظیم کرد.

گزینه شرح
Cookie تنظیمات مورد استفاده برای ایجاد کوکی های ضد جعل را تعیین می کند.
FormFieldName نام فیلد فرم پنهانی (Hidden Form Field) است که توسط سیستم ضد جعل برای ساختن توکن های ضدجعل در ویوها استفاده می شود.
HeaderName نام هدری که در سیستم ضد جعل مورد استفاده قرار می گیرد، را می توان مشخص کرد. اگر این مقدار تعیین نشود و یا تهی باشد، سیستم فقط داده های فرم را در نظر می گیرد.
SuppressXFrameOptionsHeader مشخص می کند که تولید هدر X-Frame-Options را متوقف کند یا نه. به صورت پیش فرض، هدر با مقدار "SAMEORIGIN" تولید می شود. مقدار پیش فرض مربوط به این مشخصه برابر با false است.
برای کسب اطلاعات بیشتر به مطلب CookieAuthenticationOptions مراجعه کنید.

پیکربندی ویژگی های ضد جعل با استفاده از اینترفیس IAntiForgery

IAntiForgery یک API برای پیکربندی ویژگی های ضد جعل فراهم می کند. IAntiForgery را می توان در متد Configure از کلاس Startup درخواست کرد. مثال زیر، از یک میان افزار برای تولید توکن ضد جعل استفاده کرده و آن را به عنوان پاسخی در قالب کوکی ارسال می کند.

		
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))
		{
			// The request token can be sent as a JavaScript-readable cookie, 
			// and Angular uses it by default.
			var tokens = antiforgery.GetAndStoreTokens(context);
			context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, 
			new CookieOptions() { HttpOnly = false });
		}

		return next(context);
	});
}

اعتبار سنجی لزوم وجود مکانیسم ضد جعل

ValidateAntiForgeryToken یک اکشن فیلتر (Action Filter) است که می تواند به یک action مستقل و مفرد، یک کنترلر و یا در سطح کلی برنامه اعمال شود. درخواست هایی که به Action ها ارسال می شود و این اکشن ها شامل ValidateAntiForgeryToken هستند، بلوکه می شوند، مگر، درخواست ارسال شده شامل یک توکن ضد جعل معتبر باشد.

[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 });
}	
ویژگی ValidateAntiForgeryToken از درخواست هایی که توسط این ویژگی مشخص شده اند، از جمله درخواست های HTTP GET، درخواست توکن می کند. اگر ویژگی ValidateAntiForgeryToken در سطح کل کنترلر ها اعمال شده باشد، می توانیم با ویژگی IgnoreAntiforgeryToken آن را خنثی و لغو کنیم.
ASP.NET Core از اضافه کردن خودکار توکن های ضد جعل به درخواست های GET پشتیبانی نمی کند.

توکن های ضد جعل را به صورت خودکار برای فقط درخواست های نا امن HTTP اعتبار سنجی کنید.

برنامه های ASP.NET Core، توکن های ضد جعل، برای متد های HTTP ایمن (GET، HEAD، OPTIONS و TRACE)، تولید نمی کنند. به جای استفاده گسترده از ویژگی ValidateAntiForgeryToken و سپس لغو و باطل کردن آن با ویژگی های IgnoreAntiforgeryToken، می توانید از ویژگی AutoValidateAntiforgeryToken استفاده کنید. این ویژگی به طور یکسان و همانند با صفت ValidateAntiForgeryToken عمل می کند، به استثنای اینکه برای درخواست هایی که با استفاده از روش های HTTP زیر انجام می شود نیازی به توکن وجود ندارد:
  • GET
  • HEAD
  • OPTIONS
  • TRACE
 توصیه می کنیم برای سناریو های غیر API به طور گسترده از AutoValidateAntiforgeryToken استفاده کنید. این کار تضمین می کند که اکشن های Post به طور پیش فرض محافظت می شوند. راه حل دیگر این است که به طور پیش فرض توکن های ضد جعل را نادیده بگیریم، مگر اینکه ValidateAntiForgeryToken به یک اکشن متد مشخصی اعمال شده باشد. در این سناریو محتمل است که یک اکشن متد Post بدون محافظت رها شده باشد، که این کار برنامه را در معرض حملات CSRF قرار می دهد. تمام متد های Post باید توکن ضد جعل را ارسال کنند.
API ها مکانیسم خودکاری برای ارسال بخش غیر کوکی از توکن را ندارند، پیاده سازی این کار، احتمالا نیاز به پیاده سازی آن در سمت کد استفاده کننده از این مکانیسم است، به مثال های زیر دقت کنید:

مثالی در سطح کلاس
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{	

مثالی در سطح کل برنامه
services.AddMvc(options => options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
لغو کردن ویژگی های ضد جعل در سطح کنترلر و سطح کل برنامه:
فیلتر IgnoreAntiforgeryToken برای لغو کردن نیاز یک اکشن و یا یک کنترلر به توکن ضد جعل استفاده می شود. وقتی این فیلتر را به متد اعمال کنیم، این کار قابلیت فیلتر های  ValidateAntiForgeryToken و AutoValidateAntiforgeryToken که در سطح بالاتر برنامه (کنترلر و یا سطح خود برنامه)  اعمال شده اند، را لغو می کند.
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
	[HttpPost]
	[IgnoreAntiforgeryToken]
	public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
	{
		// no antiforgery token required
	}
}

نو کردن توکن ها بعد از اعتبار سنجی

بعد از تایید اعتبار کاربر با هدایت مجدد کاربر به یک صفحه معمولی و یا Razor، باید توکن ها نو(Refresh) شوند.

جاوا اسکریپت، آژاکس(Ajax) و برنامه های تک صفحه ای
در برنامه های سنتی و متعارف مبتنی بر HTML، توکن های ضد جعل با استفاده از فیلد های فرم پنهان به سمت سرور ارسال می شوند. در برنامه های مدرن مبتنی بر جاوا اسکریپت و برنامه های تک صفحه ای(SPA)، بسیاری از درخواست ها درون برنامه و توسط کد انجام می شود، درخواست های آژاکس ممکن است از تکنیک های دیگری (مانند هدر های درخواست و کوکی) برای ارسال توکن استفاده کنند.

اگر کوکی ها برای ذخیره سازی توکن های اعتبار سنجی و اعتبار سنجی درخواست های API روی سرور استفاده می شوند. CSRF یک مشکل بالقوه است. اگر از فضای ذخیره سازی محلی برای ذخیره سازی توکن استفاده می شود، آسیب پذیری CSRF کاهش می یابد، به این دلیل که مقادیری که در فضای ذخیره سازی محلی ذخیره می شوند به هر درخواستی به صورت خودکار به سمت  سرور ارسال نمی شوند. بنابراین، استفاده از فضای ذخیره سازی محلی کاربر برای ذخیره کردن توکن های ضد جعل و ارسال توکن به عنوان هدر درخواست، رویکردی است که توصیه می شود.
جاوا اسکریپت
زمانی که در صفحات view از جاوا اسکریپت استفاده می کنیم، توکن می تواند توسط یک سرویس درون صفحه view ایجاد گردد. سرویس Microsoft.AspNetCore.Antiforgery.IAntiforgery را به صفحه view تزریق کرده و متد 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>
استفاده از این روش نیاز ما به تعامل مستقیم با تنظیم کردن کوکی های از سمت سرور و خواندن آنها از سمت مشتری، را از بین می برد.
مثال قبلی از جاوا اسکریپ استفاده می کند تا بتواند مقدار فیلد پنهان را برای هدر post آژاکس بخواند.
جاوا اسکریپت همچنین می تواند به توکن های داخل کوکی ها دسترسی پیدا کرده و از محتوای کوکی برای ایجاد هدر حاوی مقدار توکن استفاده کند.

context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });		
با فرض اینکه، اسکریپت درخواست می کند تا توکن را درون هدر "X-CSRF-TOKEN" ارسال کند، سرویس ضد جعل را طوری پیکربندی کنید تا به دنبال هدر "X-CSRF-TOKEN" باشد.

services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
مثال زیر از جاوا اسکریپت برای ایجاد درخواست آژاکس با هدر مناسب استفاده می کند:

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 == 200) {
			alert(xhttp.responseText);
		} else {
			alert('There was an error processing the AJAX request.');
		}
	}
};
xhttp.open('POST', '/api/password/changepassword', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "newPassword": "ReallySecurePassword999$$$" }));
AngularJS
AngularJS از یک قرارداد برای پرداختن به CSRF استفاده می کند. اگر سرور یک کوکی با نام  XSRF-TOKEN ارسال کند، سرویس $http در AngularJS هنگام ارسال درخواست به سرور، مقدار کوکی را به هدر درخواست اضافه می کند. این روند به صورت اتوماتیک انجام می شود. لزومی ندارد هدر به طور صریح سمت کاربر تنظیم شده باشد. نام هدر اشاره شده X-XSRF-TOKEN است. سرور موظف است که این هدر را شناسایی کرده و محتوای آن را اعتبار سنجی کند.
برای Asp.Net Core API برای کار کردن با این قرارداد در startup برنامه:
  • برنامه خود را پیکربندی کنید تا یک توکن به نام XSRF-TOKEN در کوکی ایجاد کند.
  • سرویس ضد جعل را پیکربندی کنید تا به دنبال هدر X-XSRF-TOKEN باشد.


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))
		{
			// The request token can be sent as a JavaScript-readable cookie, 
			// and Angular uses it by default.
			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)
{
	// Angular's default header name for sending the XSRF token.
	services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
}

گسترش دادن Extend antiforgery

نوع IAntiForgeryAdditionalDataProvider به توسعه دهندگان این اجازه را می دهد که بتوانند رفتار سیستم ضد جعل را با قرار دادن داده های اضافه در هر توکن، تغییر دهند. هر بار که یک توکن ایجاد می شود، متد GetAdditionalData فراخوانی می شود. و مقدار بازگشتی این متد، درون توکن ایجاد شده جاسازی می شود. پیاده ساز متد می تواند یک نشانگر زمانی(timestamp)، یا هر مقدار دیگری را برگرداند و سپس متد  ValidateAdditionalData را برای اعتبارسنجی این داده بعد از تایید اعتبار توکن فراخوانی می کند. شناسه کاربری کاربر، قبل تر در توکن ایجاد شده جاسازی شده است، بنابراین نیازی نیست که این اطلاعات را نیز درج کنیم. اگر یک توکن شامل داده های تکمیلی باشد اما هیچ پیکربندی برای  IAntiForgeryAdditionalDataProvider  تنظیم نشده باشد، داده های تکمیلی تایید اعتبار نخواهند شد.

منبع:

Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core



زهیر صفری
۱۳۹۹/۰۹/۲۷ Denmark
0
2

سشلام مهندس خیلی لطف کردید خیلی جامع بود خیر ببنید

ناصر رحمتی
۱۴۰۰/۰۱/۳۱ Iran
0
1

بسیار عالی و مفید و بسیار بسیار ضروری سپاسگزارم


نام را وارد کنید
تعداد کاراکتر باقیمانده: 1000
نظر خود را وارد کنید