هنگامی که برنامه شما با استفاده از پارامتر query string یا داده های یک فرم به یک URL هدایت می شود، می توان آن آدرس مربوط به redirect را دستکاری کرد و با یک URL مخرب جایگزین کرد. به این اتفاق یک حمله Open Redirect گفته می شود. یک مهاجم معمولاً از یک کلاهبرداری از نوع فیشینگ استفاده می کند تا شما را مجبور کند روی پیوندی به یک سایت قابل اعتماد کلیک کنید، اما سپس شما را به یک سایت مخرب هدایت می کند.
به آدرس URL زیر برای صفحه ورود نگاهی بیندازید، که معمولاً هنگام تلاش برای دسترسی به یک صفحه محافظت شده ای که به آن وارد نشده اید، مشاهده می کنید.
http://rouxacademy.com/account/login?url=http://rouxacademy.net
این پیوند، بعد از Login یک URL تغییر مسیر(Redirect) دارد. مشکل اینجاست که کاربر به یک سایت مخرب هدایت می شود که بسیار شبیه به سایت واقعی است. تنها تفاوت آن وجود .net به جای .com در پایان آن است که ممکن است خیلی مورد توجه کاربران نباشد.
پس از ورود به سایت واقعی، به یک صفحه ورود به سایت در سایت مخرب هدایت می شوید که از لحاظ ظاهری با سایت اصلی یکسان به نظر می رسد.
در این مرحله، ممکن است فکر کنید که شناسه کاربری و رمز عبور خود را اشتباه تایپ کرده اید، بنابراین دوباره آنها را وارد کنید. مهاجم بدون اینکه شما بدانید، به همین راحتی، اطلاعات ورود شما را به سرقت برده است. در اینجا توضیح می دهیم که چه کاری می توانید برای جلوگیری از حملات open redirect انجام دهید. یک راه حل ساده استفاده از متدی کمکی است که بررسی می کند آیا URL محلی (درون برنامه ای/ درون سایتی) است یا خیر.
بیایید نگاهی به کنترلر account بیندازیم و به سراغ متد از نوع پست login برویم. خود همین متد نیز از یک تغییر مسیر URL استفاده می کند. منتها توجه داشته باشید که چگونه از متد IsLocalURL برای تأیید اینکه URL واقعاً یک آدرس محلی است استفاده می کنیم. اگر آدرس مربوط به redirect محلی نیست، کاربر را به صفحه اصلی مربوط به دانشآموز هدایت میکنیم.
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);
if (result.Succeeded)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(nameof(StudentController.Index), "Student");
}
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
تهدید بالقوه دیگر دستکاری URL است. این مفهوم به یک ویرایش ساده URL در نوار آدرس مرورگر برای مشاهده یک وب سایت اشاره دارد. آدرس URL نمونه زیر را در نظر بگیرید که اطلاعات حساب یک دانش آموز را نشان می دهد.
http://www.rouxacademy.com/accountinfo?id=55&student=true
شناسه به صورت متن ساده است و حتی یک کاربر معمولی ممکن است وسوسه شود و آن را تغییر دهد یا مثلا مقدار فیلد student را به false تغییر دهد.
این کار می تواند داده های محافظت شده را برای مهاجمان آشکار کند و اثرات مخرب دیگری داشته باشد. مرورگرها می توانند تاریخچه URL ها را ضبط کنند که منجر به مشکلات امنیتی بیشتری می شود. مهم است که بدانیم URL ها به صورت عمومی در معرض دید قرار می گیرند و به راحتی قابل تغییر هستند. بهترین راه حل این است که از قرار دادن پارامترهای حساس و کلیدی در URL اجتناب کنید. اگر مجبور هستید که این پارامتر ها را از طریق URL انتقال دهید، آنها باید رمزگذاری شوند. با این کار، کاربر نمی تواند مقدار واقعی این مقادیر را ببیند و یا آنها را تغییر دهد. همچنین باید کنترل دسترسی ای وجود داشته باشد تا تأیید کند که کاربری که بر روی پارامتر کار می کند و تغییراتی در آن می دهد آیا مجاز به انجام این کار است یا خیر. در مثال ما، باید بررسی شود که آیا کاربر فعلی و لاگین کرده، اجازه مشاهده اطلاعات حساب با آی دی 55 را دارد؟ در نهایت، باید از ایجاد و پیاده سازی متد هایی با درخواستهای از نوع HttpGet ای که تغییراتی در برنامه ایجاد میکنند اجتناب کرد. متد هایی از نوع درخواست های GET باید فاقد قدرت تغییر باشد. این بدان معنی است که این متد ها و درخواست ها هیچ تغییری ایجاد نمی کند و می تواند بارها و بارها با همان نتیجه بدون اثر قبلی فراخوانی شوند.