چگونه در یک فرم MVC مانع حملات از نوع CSRF شویم؟

هنگامی که در MVC فرمی را برای عملیاتی مثل ذخیره سازی یا ویرایش به سرور ارسال می کنید، در صورتی که کاربر در فرم از تگهای Html یا کدهای JavaScript  استفاده کرده باشد ، کنترلر بصورت پیش فرض آن تگ یا کد را خطرناک تشخیص می دهد و خطای زیر را ارسال می کند :

A potentially dangerous Request.Form value was detected from the client

حتی اگر کد Html شما خطرناک هم نباشد ، باز هم این خطا داده می شود، مثلا در شکل زیر تنها یک تگ B وجود دارد که متن را توپر می کند ولی باز هم خطا صادر می شود : 

 

این خطا از لحاظ امنیتی به ما کمک می کند تا جلو کدهای احیانا مخربی را که هکرها وارد می کنند ، بگیریم ولی گاهی اوقات لازم است که ما کد Html را دریافت کنیم ، مثلا اگر شما می خواهید به کاربر اجازه درج محتویات یک صفحه خبر و یا ارسال یک ایمیل را بدهید که معمولا یک ویرایشگر متنی در اختیار کاربر قرار می گیرد که کد html تولید می کند

 برای حل این مشکل  ValidationInput  را برابر  false قرار می دهیم که باعث می شود اعتبار سنجی روی تگهای Html صورت نگیرد. در این حالت کنترلر بصورت زیر در می آید:

 

  [ValidateInput(false)]          public ActionResult NewEmail(FormCollection form(         {

اما با اینکار عملا راه را برای حمله های امنیتی از نوع Cross Site Request Forgery باز کرده ایم . این حمله ها به این صورت انجام می شود که هکر با ارسال فرمی که خودش ساخته است و قرار دادن کدهایی در آن ،  باعث ربوده شدن اطلاعاتی مثل Session از کامپیوتر کاربر می شود .

برای پیشگیری از این نوع حملات شما باید یک token از نوع encrypted تولید می کند که تنها توسط کنترلر قابل اعتبار سنجی است . بنابراین شما در ابتدای فرم خود ،  آن token را بصورت زیر تولید می کنید  :

 @using (Html.BeginForm("NewEmail""Emails"FormMethod.Post))      {          @Html.AntiForgeryToken()

و سپس در کنترلر خود آن را با عبارت [ValidateAntiForgeryToken] بررسی می کنید تا مطمئن شوید که مقادیر این فرم توسط برنامه خود شما تولید شده است. 

  [ValidateAntiForgeryToken]         [ValidateInput(false)]         public ActionResult NewEmail(FormCollection form)         {
/ 1 نظر / 255 بازدید
محسن

سلام . ممنون بابت مطلب جالبتون . سوال من اینه که وقتی اعتبارسنجی رو غیرفعال کردیم ولی از کتابخانه antiXss استفاده کنیم برای خروجی دادن اطلاعات ذخیره شده (GetSafeHtml) بازم نیازی به این روش که شما توضیح دادین هست ؟