محافظت برنامه های MVC از حملات CSRF با استفاده از Antiforgery token

یکشنبه 8 آذر 1394

Cross-site request forgery و یا CSRF یک باگ امنیتی است . درخواستی جعلی که از طریق یک سایت دیگر می‌آید.به بیان دیگر از طرف شما که مورد اعتماد یک سایتی هستید درخواست های جعلی به آن سایت ارسال می شوند.

محافظت برنامه های MVC از حملات CSRF با استفاده از Antiforgery token

Cross-site request forgery و یا CSRF یک باگ امنیتی است.درخواستی جعلی که از طریق یک سایت دیگر می‌آید .کاری که هکر ها در این روش انجام میدهند به این صورت است که برای اجرای عملیات بانکی که شامل تراکنشی برای انتقال پول به حساب دلخواهش است ، لینک انجام تراکنش را در جاهای عمومی قرار می دهد .اگر فردی در سایتی که دارای ایمنی پایینی است لاگین کند با کلیک روی لینکی که هکر قرار داده است ، مثلا پولی که قرار بود در تراکنش بانکی به جای خاصی واریز شود به حساب هکر ریخته خواهد شد .

بهتر است برای جلوگیری از این نوع هک شدن ، عملیات پولی در چند مرحله انجام شود و تنها با یک لینک کلیه عملیات انجام نشود.می توانید از Captcha یا همان کدهای امنیتی هم استفاده کنید .

به بیان دیگر از طرف شما که مورد اعتماد یک سایتی هستید درخواست های جعلی به آن سایت ارسال می شوند .مثلا اگر در یک صفحه ای در سایت برای شما امکان تغییر نام کاربری و کلمه عبورتان گذاشته شده است شما در این صفحه می توانید با زدن کاربری درست خود به تغییر کاربری و رمز عبور بپردازید .درخواست تغییر کاربری شما به سرور ارسال می شود و سرور با استفاده از کوکی هایی که مرورگر شما به سرور ارسال کرده است به شما پاسخ می دهد.اگر این درخواست از سمت شخص دیگری باشد سرور با چک کردن کوکی می فهمد که این درخواست بی اعتبار است و به آن پاسخ نمی دهد اما اگر این درخواست از کامپیوتر شما باشد بدون اینکه شما متوجه شوید در این حالت حمله CSRF رخ داده است .با کمک زبان های سمت کاربر موجود به راحتی می توان صفحه ای طراحی کرد که با ورود به آن کوکی به مربوط به سایت است از طریق آن ارسال درخواست کرد.

در MVC مکانیزم AntiForgeryToken برای جلوگیری از این نوع حمله تعبیه شده است .

وقت آن است که وارد کار عملی شویم :

یک پروژه MVC ایجاد کنید بعد از آن یک کنترلر Home ایجاد کنید .برای Action به نام ایندکس یک صفحه View ایجاد می کنیم .کد مربوط به کنترلر به صورت زیر است :

  public ActionResult Index()
        {
            return View();

        }

        [ValidateAntiForgeryToken]
        [HttpPost]
        public ActionResult Getmessage(string message)
        {
            ViewBag.message = message;
            return View("Getmessage");
        }

صفحه index.cshtml را باز کرده و کد های زیر را در آن کپی کنید

@{
    ViewBag.Title = "Index";
}

<h3>برنامه نویسان :مرجع تخصصی برنامه نویسان</h3>

<a href="http://www.barnamenevisan.org">
    <img src="~/index.jpg" />
</a>

<p>
    @using (Html.BeginForm("Getmessage", "Home"))
    {
        @Html.Label("نام خود را وارد کنید :")
        @Html.TextBox("message");
        @Html.AntiForgeryToken();

        <input type="submit" value="submit" />
    }
</p>

توجه کنید که @Html.AntiForgeryToken() شامل دو توکن می شود یک توکن به عنوان HTTP cookie ارسال می شود و دیگری به نام __RequestVerificationToken است .این Input یک نوع Hidden است وقتی شما صفحه را اجرامی کنید در سورس صفحه مقدار این فیلد را خواهید دید  با کد زیر

   <input name="__RequestVerificationToken" type="hidden"   
           value="6fGBtLasde77885qwafasdera44ad444aeadvhrgerhuk22wet[...]" />

وقتی کاربر دکمه Submit را می زند هر دو توکن از طرف کاربر به سرور ارسال می شود .این دو توکن توسط سایت های دیگر قابل خواندن نیستند

در مرحله بعد تابعی خواهیم نوشت که این دو توکن ارسالی از سمت کاربر را چک می کند .در کنترلر Home یک Action جدید به نام GetMessage  نوشته و کدهای زیر را به آن اضافه می کنیم .

@{
    ViewBag.Title = "Getmessage";
}

<h4>Getmessage</h4>
<br />
<br />
<p>
    نام شما :  @Html.Encode(ViewData["message"])
</p>

وقتی درخواست بازگشتی از طریق Post به این action می رسد ، attribute به نام [ValidateAntiForgeryToken] فیلد مخفی (توکن مخفی) و کوکی را چک می کند اگر این مقدار درست باشد آنگاه Action مورد نظر اجرا خواهد شد اگر درست نباشد آنگاه یک Exception رخ خواهد داد .

بعد از اجرا شکل زیر را خواهیم دید

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید