نمای وب – URI ناامن بارگیری می شود
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
دسته 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
منابع
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Webviews – Unsafe URI Loading\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-CODE: Code Quality](https://mas.owasp.org/MASVS/10-MASVS-CODE)\n\n\nOverview\n--------\n\nAn unsafe URI Loading occurs when an Android application fails to correctly\nevaluate the validity of a URI before loading it into a WebView.\n\nThe underlying reason behind this type of vulnerability is that a\n[URI consists of multiple parts](https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/net/URI.html), of which, at a minimum, the scheme and the\nhost (of the authority part) must be verified (e.g. allowlisted) before the URI\ngets loaded to a WebView or is used internally by the application.\n\nThe most common mistakes include:\n\n- Checking the host but not the scheme, allowing an attacker to use schemes like `http://`, `content://` or `javascript://` with an authenticated host.\n- Failing to parse the URI correctly, especially in cases where the URI is received as a string.\n- Validating the scheme but not the host (insufficient host validation).\n\nRegarding the last case, this usually occurs when the application needs to allow\narbitrary subdomains of a primary domain. So, even if the hostname has been\nextracted correctly, the app uses methods such as `startsWith`, `endsWith,` or\n`contains` of the `java.lang.String` class to validate the presence of a primary\ndomain in the extracted string section. Used incorrectly, these methods may lead\nto faulty results and force the application to improperly trust a potentially\nmalicious host.\n\nImpact\n------\n\nDepending on the context in which the host is used, the impact can vary. In\ncases where loading a malicious URI (i.e., one that bypassed\nfiltering/allowlist) in a WebView could potentially lead to account takeover\n(e.g. using phishing), code execution (e.g., loading malicious JavaScript), or\ndevice compromise (exploit code delivered using hyperlink).\n\nMitigations\n-----------\n\nWhen handling string URIs, it is important to parse the string as a URI and\nvalidate both the scheme and the host: \n\n### Kotlin\n\n fun isUriTrusted(incomingUri: String, trustedHostName: String): Boolean {\n try {\n val uri = Uri.parse(incomingUri)\n return uri.scheme == \"https\" && uri.host == trustedHostName\n } catch (e: NullPointerException) {\n throw NullPointerException(\"incomingUri is null or not well-formed\")\n }\n }\n\n### Java\n\n public static boolean isUriTrusted(String incomingUri, String trustedHostName)\n throws NullPointerException {\n try {\n Uri uri = Uri.parse(incomingUri);\n return uri.getScheme().equals(\"https\") &&\n uri.getHost().equals(trustedHostName);\n } catch (NullPointerException e) {\n throw new NullPointerException(\n \"incomingUri is null or not well-formed\");\n }\n }\n\nFor host validation, after isolating the corresponding URI part, it is important\nto validate it entirely (rather than partially) to accurately identify whether\nthe host is trusted or not. When using methods like `startsWith` or `endsWith`\ncan't be avoided, it is important to use the correct syntax and not overlook\nnecessary characters or symbols (for example, `endsWith` requires the \"`.`\" dot\ncharacter before the domain name for an accurate match). Neglecting these\ncharacters may lead to inaccurate matches and compromise security. Since\nsubdomains can be infinitely nested, regular expression matching is not a\nrecommended strategy for validating hostnames.\n\nContributors: Dimitrios Valsamaras and Michael Peck of Microsoft Threat\nIntelligence\n\nResources\n---------\n\n- [getHost() documentation](/reference/java/net/URI#getHost())\n- [getScheme() documentation](/reference/java/net/URI#getScheme())"]]