OWASP 類別: MASVS-PLATFORM:平台互動
總覽
原生橋接器 (有時也稱為 JavaScript 橋接器) 是一種機制,可使用 addJavascriptInterface 方法,促進 WebView 與原生 Android 程式碼之間的通訊。這樣一來,WebView 中執行的 JavaScript 程式碼和 Android 應用程式的 Java 程式碼就能雙向通訊。addJavascriptInterface 方法會向 WebView 的所有影格公開 Java 物件,任何影格都可以存取物件名稱並呼叫物件的方法。不過,應用程式無法驗證 WebView 中呼叫影格的來源,這會引發安全疑慮,因為內容的可信度仍不確定。
您也可以使用 Android 的 WebViewCompat.postWebMessage 或 WebMessagePort.postMessage,透過 HTML 訊息管道實作原生橋接器,與 JavaScript Window.postMessage 通訊。WebViewCompat.postWebMessage 和
WebMessagePort.postMessage 可以接受透過 Window.postMessage 傳送的 JavaScript 訊息,這些訊息會在 WebView 中執行。
原生橋接器會帶來多種風險:
- 以 JavascriptInterface 為基礎的橋接器:
addJavascriptInterface方法會將提供的 Java 物件插入 WebView 的每個影格 (包括 iframe),這表示惡意第三方可能會將影格插入合法網站,藉此發動攻擊。如果應用程式鎖定 API 級別 16 以下版本,特別容易遭受攻擊,因為這個方法可讓 JavaScript 控制主機應用程式。- 在啟用原生橋接器的 WebView 中反映不受信任的使用者提供內容,會導致跨網站指令碼攻擊 (XSS)。
- 以 MessageChannel 為基礎的橋接器:
- 如果訊息管道端點缺少來源檢查,系統就會接受任何寄件者的訊息,包括含有惡意程式碼的訊息。
- 您可能會不小心將 Java 暴露給任意 JavaScript。
影響
惡意行為人可能會利用 addJavascriptInterface、postWebMessage 和 postMessage 方法,存取、操控或將受控程式碼插入 WebView。這可能會導致使用者重新導向至惡意網站、載入惡意內容,或在裝置上執行惡意程式碼,藉此擷取私密資料或取得提權。
風險:addJavascriptInterface 風險
WebView 會實作瀏覽器的基本功能,例如網頁算繪、導覽和執行 JavaScript。您可以在應用程式中使用 WebView,在活動版面配置中顯示網路內容。在 WebView 中使用 addJavascriptInterface 方法實作原生橋接器,可能會導致跨網站指令碼攻擊 (XSS) 等安全問題,或允許攻擊者透過介面注入載入不受信任的內容,並以非預期的方式操縱主機應用程式,以主機應用程式的權限執行 Java 程式碼。
因應措施
停用 JavaScript
如果 WebView 不需要 JavaScript,請勿在 WebSettings 中呼叫 setJavaScriptEnabled (例如顯示靜態 HTML 內容時)。根據預設,WebView 會停用 JavaScript 執行作業。
載入不受信任的內容時移除 JavaScript 介面
請務必在 WebView 載入不受信任的內容前,呼叫 removeJavascriptInterface,移除 JavaScript 介面的物件。舉例來說,您可以在呼叫 shouldInterceptRequest 時執行這項操作。
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
只透過 HTTPS 載入網頁內容
如果需要載入不受信任的內容,請確保 WebView 透過加密連線載入網路內容 (另請參閱明文通訊相關規範)。如要避免在未加密的連線上執行初始載入網頁作業,請在 AndroidManifest 檔案中將 android:usesCleartextTraffic 設為 false,或在網路安全性設定中禁止 HTTP 流量。詳情請參閱 usesCleartextTraffic 說明文件。
Xml
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
為確保重新導向和後續應用程式瀏覽不會發生在未加密的流量上,請檢查 loadUrl 或 shouldInterceptRequest 中的 HTTP 通訊協定:
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。
請勿公開機密資料
如果您的應用程式會透過 WebView 存取私密資料,建議您先使用 clearCache 方法刪除儲存在本機的所有檔案,再使用 JavaScript 介面。您也可以使用伺服器端標頭 (例如 no-store),指出應用程式不應快取特定內容。
請勿公開機密功能
如果應用程式需要機密權限或會收集機密資料,請確保這些功能是從應用程式內的程式碼呼叫,並向使用者提供顯眼的揭露事項。請勿使用 JavaScript 介面執行任何敏感操作或處理使用者資料。
指定 API 級別 21 以上版本
如要安全地使用 addJavascriptInterface 方法,請指定目標 API 級別 21 以上,確保只有在 API 級別 21 以上的環境中執行方法。在 API 21 之前,JavaScript 可以使用反射存取插入物件的公開欄位。
風險:MessageChannel 風險
如果 postWebMessage() 和 postMessage() 中缺少來源控制項,攻擊者可能會攔截訊息,或將訊息傳送至原生處理常式。
因應措施
設定 postWebMessage() 或 postMessage() 時,請避免使用 * 做為目標來源,改為明確指定預期的傳送網域,只允許來自信任網域的訊息。
資源
- postMessage() 最佳做法
- addJavascriptInterface 說明文件
- postMessage() 說明文件
- WebMessagePort.postMessage() 說明文件
- WebViewClient.shouldInterceptRequest 說明文件
- 有關 addJavascriptInterface 的安全建議說明文件
- clearCache 說明文件
- removeJavascript 說明文件
- 在 WebView 中啟用 JavaScript