☰
OWASP MASTG 最佳实践 MASTG-BEST-0012:Android WebView 中 JavaScript 的安全启用与禁用策略
2026/10/5 6:51:27 网站建设 项目流程
  • 文档
  • 教程
  • 网络安全

【免费下载链接】mastg

The OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.

项目地址:https://gitcode.com/gh_mirrors/ow/mastg
点击查看免费下载

开启 JavaScript 本身并非安全漏洞,但它是 WebView 攻击面扩张的关键开关,OWASP MASTG 以最佳实践条目 MASTG-BEST-0012(Disable JavaScript in WebViews)给出了从「默认禁用」「择机启用」到「启用后的纵深加固」的完整决策路径。本文以该最佳实践为主体,结合仓库中的知识条目 MASTG-KNOW-0018、配套最佳实践与静态分析规则、以及真实 Demo 源码,讲清何时必须禁用、何时可以启用、启用后如何用安全浏览、来源白名单与桥接隔离把风险压到最低。

核心论断:启用 JavaScript 本身不是漏洞

MASTG-BEST-0012 开篇即明确一个容易被误解的事实:启用 JavaScript 并不是漏洞本身。真实应用中,JavaScript 常常是业务功能的必需品:

  • 渲染现代 Web 应用、交互式账户门户、帮助中心;
  • 支付或登录流程;
  • 用 Web 技术构建的混合应用内容。

尤其值得注意的是,Ionic 和 Capacitor 这类框架本身就是围绕一个运行 JavaScript 应用代码的 WebView 构建的,而react-native-webview的存在目的就是在原生视图中渲染 Web 内容。对这些应用来说,JavaScript 不是「可以省掉的配置」,而是应用架构的基础设施。

Android 官方将「不安全地使用开启 JavaScript 的 WebView」与 cross-app scripting(跨应用脚本) 风险关联起来。JavaScript 确实会增大 WebView 的攻击面,但严重事故通常发生在它叠加了以下一个或多个条件时:

  1. 加载不受信任或校验薄弱的内容;
  2. 暴露了 JavaScript 桥接(bridge);
  3. 允许宽松的 file / content 访问;
  4. 使用了不安全的 URL 加载方式。

换言之,JavaScript 是「放大器」而非「漏洞源」——真正决定风险的是它和谁组合。这一判断也反映在仓库测试体系中:原 MASTG-TEST-0031(Testing JavaScript Execution in WebViews) 已被标记为 deprecated,其弃用说明明确写道:启用 JavaScript 本身不再被视为独立漏洞,它只有在与其他弱点(如 WebView 本地文件访问)组合时才会导致安全问题,因此不再作为独立测试项,相关风险由 MASTG v2 中其他测试覆盖。

不需要 JavaScript 时:保持默认禁用

Android 的 WebView 中JavaScript 默认是禁用的。如果业务不需要,就不要主动打开它;如果代码中可能被打开,则显式关闭:

webView.getSettings().setJavaScriptEnabled(false);

对应 Kotlin 写法:

webView.settings.javaScriptEnabled = false

仓库知识条目 MASTG-KNOW-0018 补充了这条默认值的细节:setJavaScriptEnabled(true)是唯一能开启执行的方式,默认关闭时,页面中的任何脚本都不会运行,包括内容自带的脚本。

那么哪些 WebView 适合保持禁用?MASTG-BEST-0012 给出了明确的分类:

保持禁用(静态或极简交互内容):

  • 静态帮助页面;
  • 法律文本(Terms / Privacy);
  • 发布说明(release notes);
  • 其他不需要客户端脚本的受控内容。

可以启用(有意运行可信 Web 应用逻辑):

  • 混合应用页面;
  • 复杂的内部 Web 应用;
  • 单页应用(SPA);
  • 依赖 JavaScript 才能渲染或运行的用户界面。

这个「按内容分类决策」的思路,也被仓库的静态分析规则体系所印证。mastg-android-webview-allow-local-access.yml 中的mastg-android-webview-settings规则(INFO 级别)会把所有与 WebView 本地文件访问和 JavaScript 执行相关的设置调用(setJavaScriptEnabled、setAllowContentAccess、setAllowFileAccess、setAllowFileAccessFromFileURLs、setAllowUniversalAccessFromFileURLs)都标记出来,提示安全测试人员逐项人工确认——因为这些设置本身不是漏洞,但每打开一个都会放大攻击面。

外部内容优先用浏览器上下文:Custom Tabs 与 Trusted Web Activities

如果只是需要打开外部 Web 内容,MASTG-BEST-0012 建议优先考虑替代方案,而不是在应用内嵌 WebView:

方案适用场景安全特性
Custom Tabs打开外部网页、浏览器式流程内容渲染发生在浏览器上下文而非应用 WebView,宿主应用无法查看内容
Trusted Web Activities承载你自己控制的 Web 应用宿主应用无法直接访问 Web 内容或 Web 状态(如 cookies、localStorage)

Custom Tabs 特别适合认证及其他基于浏览器的流程——Android 官方就推荐用它做 sign-in,理由是宿主应用无法窥探内容。Trusted Web Activities 则从架构上切断了宿主对 Web 状态(cookies、localStorage)的直接访问。

需要强调的是,这两种方案只是把渲染搬出应用自己的 WebView,以降低「应用特有」的 WebView 风险,并不免除对 Web 内容本身的安全要求——你仍然要保证所承载或打开的网页自身是安全的。

MASTG-KNOW-0018 在「Alternatives to WebView」一节给出了同样的结论:Custom Tabs 与 Trusted Web Activities 让 JavaScript 运行在浏览器环境中,行为遵循浏览器的安全模型与更新周期,能力、局限与集成方式以 Android / Chrome 官方文档为准。

必须启用 JavaScript 时:WebView 的纵深加固清单

如果 JavaScript 确属必需,就要把「增大后的攻击面」用配套措施压回去。MASTG-BEST-0012 给出的加固清单如下,且每一条在仓库中都有对应的最佳实践或知识条目支撑:

1. 只加载预期且经过白名单(allowlist)的来源

MASTG-KNOW-0018 强调:测试 WebView 的第一要务是确保只有可信内容能被加载。任何新加载的页面都可能是恶意的,可能试图利用 WebView 绑定或钓鱼用户。除非在开发浏览器类应用,通常应把页面限制在应用自己的域名内,甚至从 UI 上杜绝用户往 WebView 里输入 URL。

2. 在调用loadUrl、shouldOverrideUrlLoading等 API 前校验 scheme 与 host

MASTG-KNOW-0018 详细解释了为什么这至关重要:默认情况下,WebView 内的导航请求会交给系统默认浏览器处理,恶意页面因此无法影响原应用(浏览器不与 WebView 共享 cookies 或 JavaScript 绑定)。但一旦用setWebViewClient给 WebView 指派了WebViewClient,所有导航都会被 WebView 自己接管——这是最糟糕的默认配置,任何资源(包括恶意内容)都可能被加载进 WebView。此时应用必须通过重写shouldOverrideUrlLoading和/或shouldInterceptRequest,实现白名单/黑名单模式来限制导航到可信内容。

仓库测试 MASTG-TEST-0028(Testing Deep Links) 展示了一个反面教材:攻击者控制深链参数deeplink_url后直接喂给wv.loadUrl(...),测试明确把它标记为「attacker has full control of the URL being loaded to the WebView」,并指出同一 WebView 渲染攻击者可控参数时会触发反射型 XSS(如deeplinkdemo://load.html?attacker_controlled=<svg onload=alert(1)>)。这正是「未校验来源 + 开启 JavaScript」组合拳的典型后果。

3. 除非确有需要,关闭 file 与 content 访问(@MASTG-BEST-0011 与 @MASTG-BEST-0013)

两条配套最佳实践分别给出细粒度指引:

  • MASTG-BEST-0011(Securely Load File Content in a WebView):加载本地文件内容的安全推荐做法是WebViewClient+WebViewAssetLoader,用https://URL 加载 assets 资源,从而获得安全的同源环境。若必须用file://加载本地文件,则:

    • 对默认值已安全的minSdkVersion,确保setAllowFileAccess、setAllowFileAccessFromFileURLs、setAllowUniversalAccessFromFileURLs不被使用或显式设为false;
    • 对默认值不安全的旧 API 级别,必须显式全部设为false。
  • MASTG-BEST-0013(Disable Content Provider Access in WebViews):setAllowContentAccess与其它文件访问设置不同,始终默认为true。只要不是明确需要,就应显式设为false。原因在于:虽然存在 CORS 等「护栏」,但应用自己的 content provider(即使未导出)仍可通过 WebView 访问,可能暴露内部/外部存储中的私有数据;若叠加 XSS 或不可信远程内容,攻击者就能读取敏感数据并外传。MASTG-KNOW-0018 提供了该设置默认值的精确证据:setAllowContentAccess自 Android 4.1(API level 16)起默认开启。

4. 避免向不受信任的内容暴露 JavaScript 桥接(@MASTG-BEST-0035)

MASTG-BEST-0035(Prefer Origin Scoped Messaging Over Legacy JavaScript Bridges) 给出桥接使用的安全分级:

  • 尽量避免遗留的addJavascriptInterface模型:它暴露给 WebView 中每一个 frame(含 iframe),且没有基于来源的访问控制,不适合作为安全边界。即使 target API level ≥ 21 后 JavaScript 只能访问带@JavascriptInterface注解的方法(不再能反射访问公有字段),其缺乏 origin 控制的根本缺陷仍在。仓库规则 mastg-android-webview-bridges.yml 会以 WARNING 级别检测「JavaScript 已启用 + 注册addJavascriptInterface桥」的组合,以及所有@JavascriptInterface注解方法,提示测试人员关注这类高风险组合。
  • 需要桥接时优先addWebMessageListener:这是 Android 官方文档标记为Recommended: Yes / Security: Highest (Allowlist-based)的机制。使用时配置严格的allowedOriginRules,在loadUrl()之前注册监听器,并在回调中校验发送者信息后再处理消息。
  • postWebMessage仅作备选:官方对比表中标记为Recommended: No / Security: High (Origin-aware)。若使用,必须配置严格的目标 origin,避免*通配符——缺少 origin 控制时攻击者可拦截消息或向原生处理器发送消息。
  • 无论哪种机制,都要最小化暴露给 JavaScript 的原生功能:只暴露页面确实需要的操作,避免宽泛的工具对象或通用命令分发器,不暴露非必需的敏感能力,要求简单明确的消息格式,拒绝意外输入与不支持的动作。

MASTG-KNOW-0018 还补充了桥接机制的底层事实:addWebMessageListener通过注入带postMessage/onmessage的 JavaScript 代理对象实现异步消息传递;addJavascriptInterface是同步遗留模型;在 API level 21 之前,JavaScript 可利用反射读取注入对象的公有字段,历史上存在window.jsinterface.getClass().forName('java.lang.Runtime')...exec(...)这类反射 RCE 载荷。

5. 在支持的环境开启 Safe Browsing

调用WebSettings.setSafeBrowsingEnabled(true)(Android 8.0,API level 26 起可用),让 WebView 对 Google 已标记的已知威胁 URL 向用户发出警告。MASTG-KNOW-0018 补充:Android 8.1(API level 27)引入 SafeBrowsing API,默认行为是向用户显示安全风险警告并提供「继续加载」或「停止加载」选项;应用也可通过 API 自定义遇到已知威胁时的行为(如报告威胁或直接返回安全页)。

仓库在 Safe Browsing 的检测与验证上提供了非常完整的闭环:规则 mastg-android-webview-safebrowsing.yml 分别检测 manifest 中android.webkit.WebView.EnableSafeBrowsing被设为false,以及代码中setSafeBrowsingEnabled(false)的调用;配套的 MASTG-DEMO-0156 则演示了一个关键细节:manifest 中EnableSafeBrowsing设为true并不代表实际生效——代码里的webView.getSettings().setSafeBrowsingEnabled(false)(见 MastgTestWebView_reversed.java)优先级更高,会覆盖 manifest 设置并全局关闭 Safe Browsing。移除该调用后,Safe Browsing 恢复默认启用,logcat 会显示chrome://safe-browsing/match?type=phishing这类已知恶意 URL 被拦截。因此安全测试必须同时检查 manifest 与代码两处设置。

可验证的最小代码骨架

综合以上最佳实践,一个「启用 JavaScript 但仍保持可控风险」的 WebView 配置骨架如下(Java,参数按前述原则取值):

WebView webView = findViewById(R.id.webView); WebSettings settings = webView.getSettings(); // 仅当业务确需时才开启 settings.setJavaScriptEnabled(true); // 除非必需,全部关闭本地访问 settings.setAllowFileAccess(false); settings.setAllowFileAccessFromFileURLs(false); settings.setAllowUniversalAccessFromFileURLs(false); settings.setAllowContentAccess(false); // 可用平台开启 Safe Browsing(API 26+) settings.setSafeBrowsingEnabled(true); // 注册 WebViewClient 并实现来源白名单校验 webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // 校验 scheme 与 host,仅放行白名单来源 return !isAllowlisted(url); } }); // 若确需桥接:注册监听器需在 loadUrl 之前,并配置严格 allowedOriginRules webView.loadUrl("https://trusted.example.com/app");

适用范围与边界

  • 本最佳实践platform: android,针对 Android WebView;对应 MASTG 知识条目为 MASTG-KNOW-0018。
  • 相关能力映射到 MASVS v2 的MASVS-PLATFORM(WebView 交互)与MASVS-CODE(如 Safe Browsing 开关、桥接暴露)类别。
  • MASTG-BEST-0035 同时提示其局限:origin 作用域设计本身并不能阻止攻击者控制的 JavaScript 在可信页面中执行——它必须与 JavaScript 启用策略、可信来源限制、文件访问加固组合使用,这正与本文的加固清单形成完整的纵深防御体系。
  • 本文给出的所有 API 默认值、可用版本(如 Safe Browsing 自 API 26、setAllowContentAccess自 API 16 默认开启、setAllowFileAccess自 API 30 默认关闭)均以 Android 官方文档与 MASTG-KNOW-0018 中的记载为准,实际配置请结合目标应用的minSdkVersion复核。

结论

对 Android WebView 中的 JavaScript,正确姿势不是「一律禁用」或「一律开启」,而是按内容可信度分级决策:静态受控内容保持默认禁用;外部内容优先迁移到 Custom Tabs / Trusted Web Activities;确需承载可信 Web 应用逻辑时,才开启 JavaScript,并同步完成来源白名单、URL 校验、本地文件/内容访问关闭、桥接 origin 隔离与 Safe Browsing 五道加固。OWASP MASTG 用 MASTG-BEST-0012 及其配套条目(BEST-0011、BEST-0013、BEST-0035)、知识条目 MASTG-KNOW-0018、静态分析规则与可运行 Demo,为这条决策路径提供了文档、代码与工具三重可验证支撑,可直接用于安全评审与开发落地。

  • 文档
  • 教程
  • 网络安全

【免费下载链接】mastg

The OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.

项目地址:https://gitcode.com/gh_mirrors/ow/mastg
点击查看免费下载
上一篇:python-sdk 中的 Elicitation 机制:让 MCP 工具在调用中途向用户提问
下一篇:Slang 关键字与内建语法完全解析:从词法、解析器到核心模块的实现指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询