جلوگیری از حملات CSRF و XSS

جلوگیری از حملات CSRF و XSS

بسم الله الرحمن الرحیم

جلوگیری از حملات CSRF و XSS

CSRF و XSS چیست

مثل همیشه با یک مثال این موضوع را بررسی خواهیم کرد، تصور کنید قرار است یک کد ساده برای ویرایش اطلاعات بنویسیم

public class UserProfileController : Controller
{
    public ViewResult Edit() { return View(); }
 
    public ViewResult SubmitUpdate()
    {
        // Get the user's existing profile data (implementation omitted)
        ProfileData profile = GetLoggedInUserProfile();
 
        // Update the user object
        profile.EmailAddress = Request.Form["email"];
        profile.FavoriteHobby = Request.Form["hobby"];
        SaveUserProfile(profile);
 
        ViewData["message"] = "Your profile was updated.";
        return View();
    }
}

در کد بالا ما ابتدا یک View را برای کاربر برمی گردانیم که قرار است اطلاعات آن را ویرایش کند، تصور کنید این View تغییر اطلاعات کاربری باشد. طبیعتا کاربر هنگامی که فرم اطلاعاتی را تکمیل کرد آن را Submit می کند. در این جا هیچ مشکلی نیست، البته به نظر می رسد!.

بسم الله الرحمن الرحیم

جلوگیری از حملات CSRF و XSS

CSRF و XSS چیست

مثل همیشه با یک مثال این موضوع را بررسی خواهیم کرد، تصور کنید قرار است یک کد ساده برای ویرایش اطلاعات بنویسیم

public class UserProfileController : Controller
{
    public ViewResult Edit() { return View(); }
 
    public ViewResult SubmitUpdate()
    {
        // Get the user's existing profile data (implementation omitted)
        ProfileData profile = GetLoggedInUserProfile();
 
        // Update the user object
        profile.EmailAddress = Request.Form["email"];
        profile.FavoriteHobby = Request.Form["hobby"];
        SaveUserProfile(profile);
 
        ViewData["message"] = "Your profile was updated.";
        return View();
    }
}

در کد بالا ما ابتدا یک View را برای کاربر برمی گردانیم که قرار است اطلاعات آن را ویرایش کند، تصور کنید این View تغییر اطلاعات کاربری باشد. طبیعتا کاربر هنگامی که فرم اطلاعاتی را تکمیل کرد آن را Submit می کند. در این جا هیچ مشکلی نیست، البته به نظر می رسد!.

فکر کنید یک فرد مبتدی بخواهید سایت شما را هک کند، در تست امنیت یک وب سایت می بایست ابتدا نقاط ضعف وب سایت ها را بررسی کرد. یکی از پر آسیب پذیرترین اشتباهات همین دستور بالا است که توسط ما نوشته شده است.

کد زیر را در نظر بگیرید:

<body onload="document.getElementById('fm1').submit()">
    <form id="fm1" action="http://yoursite/UserProfile/SubmitUpdate" method="post">
        <input name="email" value="hacker@somewhere.evil" />
        <input name="hobby" value="Defacing websites" />
    </form>
</body>

این کد یک کد ساده است که فرم اطلاعات را برای سرور ما ارسال می کند، اگر این اطلاعات ارسال شود چه اتفاقی می افتد ما آن را در پایگاه داده خود ثبت می کنیم! خیلی ساده به نظر می رسد اما همین دلیل ساده باعث می شود سایت های زیادی روزانه hack شوند.


یکی از راه های ساده و معمولی که MVC برای جلوگیری از حملات CSF پیشنهاد می کند استفاده از تگ AntyForgeryToken است. معمولا در تمامی مثال هایی که توسط مایکروسافت ارائه می شود این تگ قرار داده می شود، شما نیز تاکنون باید این تگ را مشاهده کرده باشید.

در ASP.NET MVC تنها درخواست های POST توسط AntiForgeryToken محافظت می شود.

@using(Html.BeginForm())
{
    <p>
        @@Html.AntiForgeryToken()
    </p>
}

نتیجه اضافه شدن دستورات بالاتگ های زیر است که باعث می شود وقتی Form ایی برای یک کاربر ارسال می شود آن فرم منحصر به فرد باشد در نتیجه وقتی شما دستور هک بالا را بخواهید اجرا کنید خطای زیر را دریافت خواهید کرد.

A required anti-forgery token was not supplied or was invalid.

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

<form ..>
...
<input type="hidden" 
    name="__RequestVerificationToken">
    value="d1Hh28W3uTpdZcEG0VhEkYg7D5XqFM9Sm4iA2e/cXgrOIIpPDENi1lVBg6mYLBAAoGk0q5RA/EPE2o6W5VAqd
         ziURtyqcdFrEcDmSID4vtOF+Nm2Zgf5EJRoRCTUzWvEgcffCvWgfATcznKjnZExjGcbMYQKLhkWBKydzzi4/UE="     
</form>

و همچنین در بالای Action هاباید به صورت زیر به کار گرفته شود:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Save(Model model)
{
    ...
}

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

@Html.AntiForgeryToken("someArbitraryString")

و در قمست Action  کد خود باید دستور زیر را بنویسید.

[ValidateAntiForgeryToken(Salt="someArbitraryString")]
public ViewResult SubmitUpdate()
{
    // ... etc
}

همانطور که مشخص است همه چیز مانند حالت پیش فرض است با این تفاوت که تنها یک String با عنوان someArbitraryString اضافه شده است. به این رشته Salt گفته میشود.

Salt چیز خاصی نیست بلکه تنها یک String است که شما آن را برای کاربر ارسال و سپس آن را مجددا دریافت می کنید.

نظرات

  • Hannah Martinez
    neda
    دو شنبه 11 دی 1278 - 0:00
    • Judith Bell
      پاسخ
      اسماعیلشیدایی
      دو شنبه 11 دی 1278 - 0:00

      باعرض سلام

      بر اساس خطای رخ داده مشخصا، شما مقدار کلید ValidateAntiForgeryToken را مقدار ثابتی قرار داده اید به همین دلیل خطای مشخص شده رخ داده است.

      سعی خواهم کرد انشالله تا چند روز آتی، آموزش ساخت Dynamic salt را بروی سایت قرار خواهم داد

      موفق باشید

  • Hannah Martinez
    neda
    دو شنبه 11 دی 1278 - 0:00

    وقتی از salt برای AntiForgeryToken استفاده میکنم خطا دارم

    در این خط هم خطا دارم
    @Html.AntiForgeryToken("someArbitraryString")
    همیشه از AntiForgeryToken  برای فرم ها استفاده می کردم 
    ولی از salt نه
    اینکه گفتید در برنامه خود فرم های مختلف را از یکدیگر محافظت کنید
    تا حالا بهش توجه نکرده بودم
    لطفا راهنمایی کنید تا بتونم ازش استفاده کنم
    ممنون

    • Judith Bell
      پاسخ
      اسماعیلشیدایی
      دو شنبه 11 دی 1278 - 0:00

      با عرض سلام

      لطفا خطای خود را در اینجا قرار دهید، تا بتوانیم مشکل را بررسی کنیم.

      موفق باشید

نظرات یا سوالات خودرا با ما درمیان بگذارید

0912 097 5516 :شماره تماس
0713 625 1757 :شماره تماس