حملات جعل درخواست بین سایتی زمانی است که کاربران فریب داده می شوند تا متد ناخواسته ای را در وب سایتی که وارد آن شده اند (لاگین کرده اند) اجرا کنند. بسیاری از سیستمهای احراز هویت با استفاده از کوکیها، اعتبارنامهها را در مرورگر ذخیره میکنند و در هر درخواست آنها را ارسال میکنند. یک مهاجم می تواند کاربر را فریب دهد و از طرف او درخواستی را همراه با اعتبارنامه های خود ارسال کند. سایت هدف نمی تواند بگوید که درخواست ارسال شده قانونی نیست. این حملات، که آنها CSRF نیز نامیده می شوند، درخواست هایی را هدف قرار می دهند که وضعیت یک برنامه را تغییر می دهند. به عنوان مثال درخواست های HTTP POST.
برای درک بهتر این نوع حمله، مثالی را در نظر می گیریم. یکی از اعضای هیئت علمی وارد سایت Roux Academy میشود و در آن لاگین می کند و مدتی بعد روی لینک ایمیلی که دریافت کرده است کلیک میکند که میگوید برنده جایزه شده است. سپس لینک مربوطه کاربر را به یک سایت مخرب می برد. سپس کاربر فریب خورده و روی دکمه ای کلیک می کند تا جایزه اش را بگیرد. سپس سایت مخرب یک فرم مخفی را به Roux Academy ارسال می کند که کلیه اطلاعات کاربری نیز توسط فرم ارسال می شود. فرم دارای فیلدهای ورودی مشابه با ویو و متد AddGrade است، اما همه آنها پنهان و از قبل پر شده اند.
حال به نحوه ارسال فرم از سایت مخرب به سایت RouxAcademy.com توجه کنید. به همین راحتی است که حمله بین سایتی (cross-site attack) اتفاق می افتد. بنابراین مهاجم میتواند نمرات دانشجویی غیر واقعی را بدون اطلاع اعضای هیئت علمی در سایت وارد کند.
راه های دیگری نیز وجود دارد که می توان حملات CSRF را اجرا کرد.
سایت مخرب می تواند به طور خودکار فرم را با استفاده از یک اسکریپت یا درخواست Ajax ارسال کند.
اگر درخواستهای GET را به نحوی پیاده سازی کنید که دیتای درون برنامه را تغییر دهد، مهاجم میتواند از یک تگ ساده تصویر با یک href برای حمله به سایت شما استفاده کند.
به همین دلیل است که تغییر وضعیت برنامه در درخواست های HTTP GET هرگز عمل خوبی نیست.به آسیب هایی فکر کنید که می تواند در برنامه های دیگر ایجاد شود، یا اگر مشخصات ورود یک کاربر مدیر لو برود. در این صورت یک مهاجم می تواند در یک اپلیکیشن بانکی پول را از یک حساب به یک حساب دیگر منتقل کند یا اطلاعات کاربر را تغییر دهد. حال بیایید نگاه کنیم که چگونه ASP.NET Core MVC در برابر این نوع حملات دفاع می کند.
این دفاعی که گفتیم، شامل یک بسته anti-forgery (ضد جعل) است که الگوی رمزگذاری توکن را پیاده سازی می کند. سرور دو توکن رمزگذاری شده anti-forgery (ضد جعل) تولید می کند و آنها را به مرورگر کاربر ارسال می کند.
یکی از توکن ها، توکن کوکی است که یک مقدار تصادفی را در خود ذخیره می کند و دیگری یک توکن درخواست است که همان مقدار تصادفی و برخی داده های اضافی را در مورد کاربر احراز هویت شده ذخیره می کند. در هر درخواست از مرورگر، سرور دو توکن را بررسی می کند تا مطمئن شود که آنها هنوز هم دیتای یکسانی دارند.
همچنین بررسی میکند که دادههای توکن درخواست با کاربر احراز هویت شده مطابقت داشته باشد. در غیر این صورت درخواست رد می شود. فرد مهاجم نمی تواند این توکن ها را جعل کند زیرا هر دو رمزگذاری شده اند. بیایید وارد کد شویم و اعتبار سنجی توکن ضد جعل را تنظیم کنیم.
بیایید Controller دانش آموز را باز کرده و متد درج نمره (AddGrade) را پیدا کنیم. ما از این متد در برابر حمله CSRF محافظت خواهیم کرد.
ما به سادگی میتوانیم از یکی از فیلترهای ضد جعل موجود، ValidateAntiForgeryToken استفاده کنیم. این را میتوان در سطح Controller نیز اضافه کرد، اما پس از آن، بدون در نظر گرفتن نوع HTTP، برای همه Action ها اعمال میشود.
[HttpPost]
[Authorize(Policy = "FacultyOnly")]
[ValidateAntiForgeryToken]
public IActionResult AddGrade(CourseGrade model)
{
if (!ModelState.IsValid)
return View();
model.CreatedBy = User.Identity.Name;
model.CreatedDate = DateTime.Now;
_db.Grades.Add(model);
_db.SaveChanges();
return RedirectToAction(nameof(StudentController.Index), "Student");
}
بهتر است در این مورد از AutoValidateAntiforgeryToken استفاده کنید. در این صورت این فیلتر برای همه درخواستهای ناامن در Controller اعمال میشود و Action های HTTP GET را مستثنی میکند. در مواردی که نیاز به اعتبارسنجی برای یک درخواست ناامن را ندارید، می توانیم از فیلتر IgnoreAntiforgeryToken استفاده کنیم.
یک قدم دیگر باقی مانده است. ما باید توکنهای ضد جعل را در تمام درخواستهای صفحه افزودن نمره اضافه کنیم. پس بیایید جلو برویم و ویو مربوطه را باز کنیم. هنگامی که یک فرم و یک ویوی Razor را با استفاده از tag-helper های MVC ایجاد می کنیم، مانند آنچه در اینجا انجام دادیم، به طور خودکار توکن درخواست را در یک فیلد فرم مخفی اضافه می کند. اما اگر به جای آن از tag-helper های html استفاده میکنید، میتوانید به صورت دستی توکن را تولید کنید.
از این کد برای این کار استفاده می کنیم:
@Html.AntiForgeryToken
ما آماده ایم تا این را آزمایش کنیم. بیایید پیش برویم و پروژه Roux Academy را اجرا کنیم.
من به عنوان عضو هیئت علمی وارد می شوم. و اکنون به صفحه افزودن نمره دسترسی خواهم داشت. بیایید html موجود در این صفحه را بررسی کنیم.
میتوانید در اینجا، فیلد فرم پنهان را ببینید که توکن درخواست رمزگذاری شده را ذخیره میکند.
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8AZQyCzB2phMnA1KW472q-_UR29T7wuSyiHJxQeghtJBdDjNeJGX68s49OJYO6S3vOZdFBXfK0ZdpBl7206V7PN5SnOfcre4vhD1NcDVF2wtKBmeX0wGyqjb4LZcyZgIORDUF_DI2USMrdxU5KVqBom9X-XU5YSUONt4PY92zn9KF0-z_7yYLZUcY77mRcmjTg">
ادامه می دهیم و یک نمره جدید اضافه می کنیم. بیایید این نمره را برای رشته علوم کامپیوتر اضافه کنیم و از شناسه کاربری دانشجویی که قبلا ایجاد شده است استفاده خواهیم کرد. دیدید که با فعال بودن اعتبار سنجی ضد جعل، توانستیم با موفقیت نمره جدیدی اضافه کنیم.
حالا بیایید توکن ضد جعل را در فرم غیرفعال کنیم تا بتوانیم یک حمله CSRF را شبیه سازی کنیم. با تنظیم ASP anti-forgery روی false می توانید این کار را انجام دهید. این فقط برای این نسخه ی نمایشی است. در پروژه های اصلی از انجام این کار اجتناب می کنیم. و بیایید دوباره یک نمره اضافه کنیم. از آنجا که action درون کنترلر ما دارای اعتبار سنجی ضد جعل است، درخواست رد شده و تنها چیزی که من می بینم یک صفحه خالی است.
همانطور که در این درس دیدیم، ASP.NET Core ابزارهایی را برای محافظت در برابر حملات Cross-site request forgery با حداقل تنظیمات به ما می دهد.