فئة OWASP: MASVS-PLATFORM: التفاعل مع المنصة
نظرة عامة
الجسر الأصلي، الذي يُعرف أحيانًا باسم جسر JavaScript، هو آلية تُسهِّل التواصل بين WebView ورمز Android الأصلي، ويتم ذلك باستخدام addJavascriptInterface
. يتيح ذلك تبادل الرسائل في اتجاهين بين رمز JavaScript الذي يتم تشغيله في WebView ورمز Java لتطبيق Android. تُعرِض الطريقة addJavascriptInterface
كائن Java
لجميع إطارات WebView، ويمكن لأي إطار الوصول إلى اسم الكائن
وتنفيذ الإجراءات عليه. ومع ذلك، لا توجد آلية للتطبيق
التحقق من مصدر إطار الاتصال داخل WebView، مما يزيد من مستوى الأمان
المخاوف، لأن مصداقية المحتوى تبقى غير مؤكدة.
يمكن أيضًا تنفيذ جسر أصلي باستخدام قنوات رسائل HTML باستخدام WebViewCompat.postWebMessage
أو
WebMessagePort.postMessage
من Android للتواصل مع Window.postMessage
من JavaScript. يمكن أن يقبل كلّ من WebViewCompat.postWebMessage
و
WebMessagePort.postMessage
رسائل JavaScript المُرسَلة من خلال
Window.postMessage
والتي سيتم تنفيذها داخل WebView.
هناك مخاطر متعددة مرتبطة بالجسور الأصلية:
- الجسور المستندة إلى JavaScriptInterface:
- تُدخل الطريقة
addJavascriptInterface
عنصر Java مزوَّدًا في كل إطار من WebView، بما في ذلك إطارات iframe، ما يعني أنّه معرّض للهجوم من قِبل جهات خارجية ضارة تُدخل إطارات في موقع إلكتروني مشروع. إنّ التطبيقات التي تستهدف المستوى 16 لواجهة برمجة التطبيقات أو الإصدارات الأقدم معرّضة بشكل خاص لخطر التعرّض لهجوم، لأنّه يمكن استخدام هذه الطريقة للسماح لـ JavaScript بالتحكّم في التطبيق المضيف. - إنّ عرض محتوى غير موثوق به يقدّمه المستخدم في مكوّنات WebView التي تم تفعيل الربط الأصلي فيها يسمح بهجمات النصوص البرمجية على المواقع الإلكترونية (XSS).
- تُدخل الطريقة
- الجسور المستندة إلى MessageChannel:
- يعني عدم التحقّق من المصدر في نقاط نهاية قناة الرسائل أنّه سيتم قبول الرسائل من أي مُرسِل، بما في ذلك الرسائل التي تحتوي على رمز ضار.
- من الممكن أن يتم عن طريق الخطأ تعريض Java لبرنامج JavaScript عشوائي.
التأثير
يمكن أن يستفيد الفاعلون الضارون من الطريقتَين addJavascriptInterface
وpostWebMessage
وpostMessage
للوصول إلى رمز برمجي يتحكّمون فيه أو التلاعب به أو حقنه
في WebView. قد يؤدي ذلك إلى إعادة توجيه المستخدمين إلى مواقع ضارّة،
أو تحميل محتوى ضار أو تشغيل شفرة ضارة على أجهزتهم
استخراج البيانات الحساسة أو تحقيق تصعيد الامتيازات.
الخطر: مخاطر addJavascriptInterface
ينفذ WebView الوظائف الأساسية للمتصفح، مثل عرض الصفحة،
والتنقل، وتنفيذ JavaScript. يمكن استخدام WebView داخل تطبيق
لعرض محتوى الويب كجزء من تنسيق نشاط. تنفيذ إعلان مدمج مع المحتوى
جسر ضمن WebView باستخدام طريقة addJavascriptInterface
يمكن أن ينشئوا
المشكلات الأمنية مثل البرمجة النصية على مستوى المواقع (XSS)، أو التي تسمح للمهاجمين بتحميل
محتوى غير موثوق به من خلال إدخال الواجهة ومعالجة المضيف
بطرق غير مقصودة، حيث يتم تنفيذ رمز Java باستخدام أذونات
المضيف.
إجراءات التخفيف
إيقاف JavaScript
في الحالات التي لا يتطلب فيها WebView وجود JavaScript، لا تستدعي
setJavaScriptEnabled
ضمن WebSettings
(على سبيل المثال، بينما
عرض محتوى HTML ثابت). يتم إيقاف تنفيذ JavaScript تلقائيًا في
WebView.
إزالة واجهة JavaScript عند تحميل محتوى غير موثوق به
تأكَّد من إزالة الكائنات من واجهة JavaScript من خلال استدعاء
removeJavascriptInterface
قبل تحميل المحتوى غير الموثوق به من خلال
WebView. على سبيل المثال، يمكن إجراء ذلك في طلب برمجي إلى
shouldInterceptRequest
.
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
تحميل محتوى الويب عبر HTTPS فقط
إذا كنت بحاجة إلى تحميل محتوى غير موثوق به، تأكَّد من أنّ WebView يحمِّل محتوى الويب من خلال اتصال مشفَّر (اطّلِع أيضًا على إرشاداتنا حول مراسلات
النصّ الواضح). منع تنفيذ التحميل الأولي للصفحة على
الاتصالات غير المشفَّرة من خلال ضبط android:usesCleartextTraffic
على false
في
ملف AndroidManifest
أو منع حركة مرور HTTP في أمان الشبكة
. اطّلِع على مستندات usesCleartextTraffic
لمزيد من المعلومات.
المعلومات.
حجم كبير جدًا
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
لضمان عدم حدوث عمليات إعادة توجيه ومزيد من تصفُّح التطبيقات على ملف تعريف الارتباط
غير المشفَّر، تحقَّق من مخطّط HTTP في loadUrl
أو
shouldInterceptRequest
:
Kotlin
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
Java
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
التحقّق من صحة المحتوى غير الموثوق به
إذا تم تحميل أي روابط خارجية في WebView، تحقَّق من أنّ المخطّط والمضيف. (نطاقات القائمة المسموح بها). يجب أن يفتح المتصفّح التلقائي أي نطاقات غير مُدرَجة في القائمة المسموح بها.
عدم تحميل محتوى غير موثوق به
إذا أمكن، حمِّل فقط عناوين URL ذات النطاق الصارم والمحتوى المملوك للتطبيق مطوّر البرامج إلى WebView.
عدم الكشف عن البيانات الحسّاسة
إذا كان تطبيقك يصل إلى البيانات الحسّاسة باستخدام WebView، ننصحك باستخدام أسلوب
clearCache
لحذف أي ملفات مخزّنة على الجهاز قبل استخدام
واجهة JavaScript. يمكنك أيضًا استخدام الرؤوس من جهة الخادم، مثل no-store، لتحديد أنّه لا يجب على التطبيق تخزين محتوى معيّن مؤقتًا.
عدم عرض وظائف حسّاسة
إذا كان تطبيقك يتطلب أذونات حسّاسة أو يجمع بيانات حسّاسة، والتأكد من طلبه من الرمز البرمجي داخل التطبيق وإبراز الإفصاح للمستخدمين. تجنَّب استخدام واجهات JavaScript لأي عمليات حساسة أو بيانات مستخدمين.
استهداف المستوى 21 من واجهة برمجة التطبيقات أو المستويات الأعلى
من الطرق الآمنة لاستخدام طريقة addJavascriptInterface
هي استهداف المستوى 21
أو أعلى لواجهة برمجة التطبيقات من خلال التأكّد من عدم استدعاء الطريقة إلا عند التشغيل على المستوى 21
أو أعلى لواجهة برمجة التطبيقات. قبل واجهة برمجة التطبيقات 21، كان بإمكان JavaScript استخدام الانعكاس للوصول إلى واجهة برمجة التطبيقات العامة
الخاصة بالكائن الذي تم إدخاله.
المخاطر: مخاطر MessageChannel
يمكن أن يؤدي عدم توفّر عنصر التحكّم في المصدر في postWebMessage()
وpostMessage()
إلى السماح للمهاجمين باعتراض الرسائل أو إرسال الرسائل إلى معالِجات أصلية.
إجراءات التخفيف
عند إعداد postWebMessage()
أو postMessage()
، السماح بالرسائل من
النطاقات الموثوق بها من خلال تجنب استخدام * كأصل مستهدف، وبدلاً من
تحديد نطاق الإرسال المتوقع بشكل صريح.
المراجع
- أفضل الممارسات المتعلّقة بالدالة postMessage()
- مستندات addJavascriptInterface
- وثائق postMessage()
- مستندات WebMessagePort.postMessage()
- مستندات WebViewClient.shouldInterceptRequest
- مستندات نصائح الأمان بشأن addJavascriptInterface
- مستندات clearCache
- مستندات removeJavascript
- تفعيل JavaScript في مكوّنات WebView