קטגוריה ב-OWASP: MASVS-PLATFORM: Platform Interaction
סקירה כללית
גשר מקורי, שנקרא לפעמים 'גשר JavaScript', הוא מנגנון
שמאפשר תקשורת בין WebView לבין קוד Android נייטיב, באמצעות
באמצעות השיטה addJavascriptInterface
. כך אפשר
תקשורת בין קוד JavaScript שפועל ב-WebView לבין Android
בקוד Java של האפליקציה. השיטה addJavascriptInterface
חושפת Java
לכל המסגרות של WebView, וכל מסגרת יכולה לגשת לשם האובייקט.
ולמידע על שיטות הקריאה. עם זאת, אין לאפליקציה מנגנון לאימות המקור של המסגרת הקוראת ב-WebView, מה שעלול לעורר חששות אבטחה כי לא ניתן לקבוע בוודאות את מהימנות התוכן.
ניתן גם להטמיע גשר מקורי באמצעות ערוצי הודעות HTML באמצעות
WebViewCompat.postWebMessage
של Android או
WebMessagePort.postMessage
כדי לתקשר עם JavaScript
Window.postMessage
. WebViewCompat.postWebMessage
והקבוצה
WebMessagePort.postMessage
יכול לקבל הודעות JavaScript שנשלחות באמצעות
Window.postMessage
שיופעל בתוך ה-WebView.
יש מספר סיכונים הקשורים לגשרים מקומיים:
- גשרים שמבוססים על JavascriptInterface:
- ה-method
addJavascriptInterface
מחדירה אובייקט Java שסופק כל מסגרת ב-WebView, כולל iframes, כלומר חשופים מתקפה על ידי צדדים שלישיים זדוניים שמחדירים פריימים לאתר לגיטימי. אפליקציות שמטרגטות לרמת API 16 או גרסאות קודמות נמצאות בסיכון גבוה במיוחד מתקפה כי השיטה הזו יכולה לשמש כדי לאפשר ל-JavaScript לשלוט במארח תרגום מכונה. - ייצוג של תוכן לא מהימן שהמשתמשים סיפקו ברכיבי WebView מותאמים לגשר שמאפשר התקפות חוצות-אתרים (cross-site scripting) (XSS).
- ה-method
- גשרים מבוססי-ערוץ Message:
- אם אין בדיקות מקור בנקודות הקצה של ערוץ ההודעות, ההודעות להתקבל מכל שולח, כולל משתמשים שמכילים קוד זדוני.
- יכול להיות ש-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 טוען תוכן אינטרנט באמצעות
חיבור מוצפן (אפשר לעיין גם בהנחיות שלנו לגבי Cleartext
תקשורת). כדי למנוע את הטעינה הראשונית של הדף בחיבור ללא הצפנה, מגדירים את android:usesCleartextTraffic
לערך false
בקובץ AndroidManifest
או אוסרים על תעבורת HTTP בתצורת אבטחת הרשת. למידע נוסף, עיינו במסמכי התיעוד של usesCleartextTraffic
.
XML
<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, צריך לאמת גם את הסכימה וגם את המארח (רשימת הדומיינים המורשים). כל דומיין שלא נמצא ברשימת ההיתרים צריך להיפתח באמצעות כדפדפן ברירת המחדל.
לא לטעון תוכן לא מהימן
אם אפשר, כדאי לטעון ב-WebView רק כתובות URL ותוכן שנמצאים בבעלות מפתח האפליקציות.
הימנעות מחשיפת מידע אישי רגיש
אם האפליקציה שלכם ניגשת למידע אישי רגיש באמצעות WebView, מומלץ להשתמש ב-method clearCache
כדי למחוק את כל הקבצים ששמורים באופן מקומי, לפני שמשתמשים בממשק JavaScript. אפשר גם להשתמש בכותרות בצד השרת, כמו No-store, כדי
לציין שאפליקציה לא צריכה לשמור תוכן מסוים במטמון.
לא לחשוף פונקציות רגישות
אם האפליקציה דורשת הרשאות רגישות או אוספת מידע אישי רגיש, לוודא קריאה מתוך הקוד בתוך האפליקציה, ושהקריאה מוצג למשתמשים. להימנע משימוש בממשקי JavaScript פעולות רגישות או נתוני משתמשים.
רמת ה-API לטירגוט צריכה להיות 21 ומעלה
אחת מהדרכים המאובטחות להשתמש ב-method addJavascriptInterface
היא לטרגט את רמת ה-API
21 ואילך, כי מוודאים שה-method מופעלת רק כשמריצים את השיטה ברמת API 21
ומעלה. לפני API 21, JavaScript יכול היה להשתמש בהשתקפות כדי לגשת לשדות הציבוריים של אובייקט שהוזן.
סיכון: סיכונים של MessageChannel
היעדר בקרת מקורות ב-postWebMessage()
וב-postMessage()
עלול לאפשר
תוקפים כדי ליירט הודעות או לשלוח הודעות לרכיבי handler מקוריים.
מיטיגציות
כשמגדירים את postWebMessage()
או postMessage()
, מותר לאפשר רק הודעות מאת
בדומיינים מהימנים על ידי הימנעות משימוש ב-* כמקור היעד, ובמקום זאת
לציין במפורש את הדומיין השולח הצפוי.
משאבים
- שיטות מומלצות ל-postMessage()
- מסמכי תיעוד שלaddJavaScriptInterface
- מסמכי התיעוד של postMessage()
- מסמכי התיעוד של WebMessagePort.postMessage()
- מסמכי התיעוד של WebViewClient.לשחזרInterceptRequest
- מסמכי עזרה בנושאי אבטחה לגבי addJavascriptInterface
- מסמכי התיעוד של clearCache
- הסרת תיעוד של JavaScript
- הפעלת JavaScript ברכיבי WebView