رده OWASP: MASVS-CODE: کیفیت کد
نمای کلی
بارگذاری ناامن URI زمانی رخ میدهد که یک برنامه اندروید نتواند اعتبار یک 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 برای تطابق دقیق به کاراکتر نقطه " . " قبل از نام دامنه نیاز دارد). نادیده گرفتن این کاراکترها ممکن است منجر به تطابق نادرست و به خطر افتادن امنیت شود. از آنجایی که زیردامنهها میتوانند بینهایت تودرتو باشند، تطبیق عبارت منظم یک استراتژی توصیه شده برای اعتبارسنجی نامهای میزبان نیست.
مشارکتکنندگان: دیمیتریوس والساماراس و مایکل پک از بخش اطلاعات تهدید مایکروسافت