دسته OWASP: MASVS-CODE: کیفیت کد
نمای کلی
بارگیری URI ناامن زمانی اتفاق میافتد که یک برنامه Android نتواند اعتبار یک URI را قبل از بارگیری آن در WebView به درستی ارزیابی کند.
دلیل اصلی پشت این نوع آسیبپذیری این است که یک URI از بخشهای متعددی تشکیل شده است که حداقل، طرح و میزبان (بخش مرجع) باید قبل از بارگیری URI در WebView تأیید شوند (مثلاً در لیست مجاز) قرار بگیرند. یا به صورت داخلی توسط برنامه استفاده می شود.
رایج ترین اشتباهات عبارتند از:
- بررسی میزبان اما نه طرح، به مهاجم اجازه میدهد از طرحهایی مانند
http://
،content://
یاjavascript://
با یک میزبان احراز هویت شده استفاده کند. - تجزیه نشدن URI به درستی، به خصوص در مواردی که URI به صورت رشته دریافت می شود.
- در حال اعتبار سنجی طرح اما نه میزبان (تأیید اعتبار میزبان ناکافی است).
در مورد آخرین مورد، این معمولاً زمانی اتفاق میافتد که برنامه نیاز دارد به زیر دامنههای دلخواه یک دامنه اصلی اجازه دهد. بنابراین، حتی اگر نام میزبان به درستی استخراج شده باشد، برنامه از روشهایی مانند startsWith
، endsWith,
یا contains
کلاس java.lang.String
استفاده میکند تا وجود یک دامنه اصلی در بخش رشته استخراجشده را تأیید کند. استفاده نادرست از این روش ها ممکن است منجر به نتایج معیوب شود و برنامه را مجبور کند که به یک میزبان بالقوه مخرب اعتماد نادرست داشته باشد.
تاثیر
بسته به زمینه ای که میزبان در آن استفاده می شود، تأثیر آن می تواند متفاوت باشد. در مواردی که بارگیری یک URI مخرب (یعنی URI که فیلتر/لیست مجاز را دور زده است) در WebView میتواند به طور بالقوه منجر به تصاحب حساب (مثلاً با استفاده از فیشینگ)، اجرای کد (مثلاً بارگیری جاوا اسکریپت مخرب)، یا به خطر افتادن دستگاه (کد سوء استفاده ارائه شده با استفاده از آن) شود. هایپرلینک).
اقدامات کاهشی
هنگام مدیریت URI های رشته ای، تجزیه رشته به عنوان URI و اعتبارسنجی طرح و میزبان مهم است:
کاتلین
fun isUriTrusted(incomingUri: String, trustedHostName: String): Boolean {
try {
val uri = Uri.parse(incomingUri)
return uri.scheme == "https" && uri.host == trustedHostName
} catch (e: NullPointerException) {
throw NullPointerException("incomingUri is null or not well-formed")
}
}
جاوا
public static boolean isUriTrusted(String incomingUri, String trustedHostName)
throws NullPointerException {
try {
Uri uri = Uri.parse(incomingUri);
return uri.getScheme().equals("https") &&
uri.getHost().equals(trustedHostName);
} catch (NullPointerException e) {
throw new NullPointerException(
"incomingUri is null or not well-formed");
}
}
برای اعتبار سنجی میزبان، پس از جداسازی بخش URI مربوطه، مهم است که آن را به طور کامل (و نه جزئی) اعتبارسنجی کنید تا به طور دقیق مشخص شود که آیا میزبان مورد اعتماد است یا خیر. وقتی نمی توان از روش هایی مانند startsWith
یا endsWith
اجتناب کرد، مهم است که از نحو صحیح استفاده کنید و از کاراکترها یا نمادهای ضروری غافل نشوید (مثلاً endsWith
برای تطبیق دقیق به کاراکتر نقطه " .
" قبل از نام دامنه نیاز دارد). نادیده گرفتن این شخصیت ها ممکن است منجر به تطابق نادرست و به خطر افتادن امنیت شود. از آنجایی که زیر دامنه ها می توانند بی نهایت تو در تو باشند، تطبیق عبارات منظم یک استراتژی توصیه شده برای اعتبارسنجی نام میزبان نیست.
مشارکت کنندگان: دیمیتریوس والساماراس و مایکل پک از Microsoft Threat Intelligence