OWASP 类别:MASVS-PLATFORM:平台互动
概览
原生桥梁(有时称为 JavaScript 桥梁)是一种机制,可促进 WebView 与原生 Android 代码之间的通信,方法是使用 addJavascriptInterface
方法。这样便可实现双向
在 WebView 中运行的 JavaScript 代码与 Android
应用的 Java 代码addJavascriptInterface
方法公开了一个 Java
对象添加到 WebView 的所有框架,并且任何框架都可以访问对象名称
并对其调用方法不过,应用并没有任何
在 WebView 中验证调用帧的来源,从而提高安全性
因为内容的可信度仍然不确定。
原生桥也可以实现 HTML 消息通道,方法是使用
Android 的 WebViewCompat.postWebMessage
或
WebMessagePort.postMessage
,以便与 JavaScript 进行通信
Window.postMessage
。WebViewCompat.postWebMessage
和
WebMessagePort.postMessage
可接受通过
Window.postMessage
(将在 WebView 中执行)。
与原生桥接相关的风险有多个:
- 基于 JavaScriptInterface 的桥:
<ph type="x-smartling-placeholder">
- </ph>
addJavascriptInterface
方法会将提供的 Java 对象注入 每个帧(包括 iframe),这意味着它容易受到 恶意第三方将框架注入合法网站的攻击。 以 API 级别 16 或更低级别为目标平台的应用特别容易受到攻击,因为此方法可用于允许 JavaScript 控制主机应用。- 在支持原生桥接的 WebView 中反映不受信任的用户提供的内容 允许跨站脚本攻击 (XSS) 攻击。
- 基于 MessageChannel 的网桥:
<ph type="x-smartling-placeholder">
- </ph>
- 未对消息通道端点进行源站检查意味着消息 (包括包含恶意代码的发件人在内)。
- 可能会意外将 Java 公开给任意 JavaScript。
影响
addJavascriptInterface
、postWebMessage
和 postMessage
方法可以
被恶意行为者利用,以访问、操纵或注入他们控制的代码
转换为 WebView。这可能会导致用户被重定向到恶意网站、加载恶意内容,或者在其设备上运行恶意代码,从而提取敏感数据或提升权限。
风险:addJavascriptInterface 风险
WebView 可实现浏览器的基本功能,例如页面渲染、
导航和 JavaScript 执行。WebView 可在应用内使用,以便在 activity 布局中显示 Web 内容。使用 addJavascriptInterface
方法在 WebView 中实现原生桥接可能会导致跨站脚本 (XSS) 等安全问题,或者允许攻击者通过接口注入加载不受信任的内容,并以意想不到的方式操纵主机应用,使用主机应用的权限执行 Java 代码。
缓解措施
停用 JavaScript
在 WebView 不需要 JavaScript 的情况下,请勿在 WebSettings
中调用 setJavaScriptEnabled
(例如,在显示静态 HTML 内容时)。默认情况下,WebView 中 JavaScript 执行功能处于停用状态。
在加载不受信任的内容时移除 JavaScript 接口
确保通过调用 JavaScript 接口中的对象来删除
removeJavascriptInterface
,然后
WebView。例如,您可以在调用 shouldInterceptRequest
时执行此操作。
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
仅通过 HTTPS 加载网络内容
如果您需要加载不受信任的内容,请确保 WebView 通过加密连接加载 Web 内容(另请参阅我们关于明文通信的准则)。禁止在以下位置执行初始网页加载
将 android:usesCleartextTraffic
设置为 false
,从而
AndroidManifest
文件,或在网络安全设置中禁止 HTTP 流量
配置。如需了解详情,请参阅 usesCleartextTraffic
文档。
Xml
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
确保在未加密的情况下不会进行重定向和进一步浏览应用
请查看 loadUrl
中的 HTTP 协议,或者
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 中加载了任何外部链接,请同时验证 scheme 和主机 (将网域列入许可名单)。所有不在许可名单中的网域都应改为由默认浏览器打开。
请勿加载不可信的内容
如果可能,请仅在 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