允许列表

域名允许列表是一种安全模型,用于控制对应用程序无法控制的外部域的访问。Cordova 提供了一个可配置的安全策略来定义可以访问哪些外部站点。

默认情况下,新应用配置为允许访问任何站点。在将应用程序投入生产之前,您应该制定一个允许列表,以提供对特定网络域和子域的访问权限。

虽然可以实现您自己的允许列表插件,但不建议这样做,除非您的应用程序需要非常特定的安全策略。

网络请求允许列表

Cordova 遵循 W3C Widget Access 规范,该规范依赖于应用程序 config.xml 文件中的 <access> 元素,该文件位于项目的顶层目录中。

这控制允许向特定域发出哪些网络请求(图像、XHR 等)(通过 cordova 原生钩子)。

注意:建议使用内容安全策略 (CSP)(见下文),这更安全。此网络请求允许列表主要用于不支持 CSP 的 webview 的历史遗留。

config.xml 中,添加 <access> 标签,如下所示

<!-- Allow images, xhrs, etc. to google.com -->
<access origin="http://google.com" />
<access origin="https://google.com" />

<!-- Access to the subdomain maps.google.com -->
<access origin="http://maps.google.com" />

<!-- Access to all the subdomains on google.com -->
<access origin="http://*.google.com" />

<!-- Enable requests to content: URLs -->
<access origin="content:///*" />

<!-- Don't block any requests -->
<access origin="*" />

没有任何 <access> 标签,只允许请求到应用程序内容所在的地址。

注意:允许列表无法阻止从允许列表中的远程网站(即 httphttps)到非允许列表网站的网络重定向。使用 CSP 规则来缓解对支持 CSP 的 webview 的非允许列表网站的重定向。

请注意,某些网站可能会自动将其主页重定向到其他 URL。示例场景可能包括但不限于

  • http 协议请求重定向到安全的 https SSL/TSL 协议。
  • 重定向到特定国家/地区的域名。例如,根据设备所在位置将 https://www.google.com 重定向到 https://www.google.co.uk

这种情况可能需要修改允许列表或在允许列表中添加超出初始要求的其他条目。在构建应用程序的允许列表时,请考虑这一点。

怪癖:Android 默认还允许请求 https://ssl.gstatic.com/accessibility/javascript/android/,因为这是 TalkBack 正常运行所必需的。

导航允许列表

这控制 WebView 本身可以导航到哪些 URL。它仅适用于顶级导航。

默认情况下,仅允许导航到 file:// URL。要允许其他 URL,您必须将 <allow-navigation> 标签添加到您的 config.xml 中。

<!-- Allow links to example.com -->
<allow-navigation href="http://example.com/*" />

<!-- Wildcards are allowed for the protocol, as a prefix
     to the host, or as a suffix to the path -->
<allow-navigation href="*://*.example.com/*" />

<!-- 
    A wildcard can be used to allow the entire network, over HTTP and HTTPS.
    This is *NOT RECOMMENDED*
-->
<allow-navigation href="*" />

<!-- The above is equivalent to these three declarations -->
<allow-navigation href="http://*/*" />
<allow-navigation href="https://*/*" />
<allow-navigation href="data:*" />

怪癖:在 Android 上,它也适用于非 http(s) 方案的 iframe。

意图允许列表

这控制允许应用程序请求系统打开哪些 URL。

config.xml 中,添加 <allow-intent> 标签,如下所示

<!-- Allow links to web pages to open in a browser -->
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />

<!-- Allow links to example.com to open in a browser -->
<allow-intent href="http://example.com/*" />

<!-- Wildcards are allowed for the protocol, as a prefix
     to the host, or as a suffix to the path -->
<allow-intent href="*://*.example.com/*" />

<!-- Allow SMS links to open messaging app -->
<allow-intent href="sms:*" />

<!-- Allow tel: links to open the dialer -->
<allow-intent href="tel:*" />

<!-- Allow geo: links to open maps -->
<allow-intent href="geo:*" />

<!-- Allow all unrecognized URLs to open installed apps
     *NOT RECOMMENDED* -->
<allow-intent href="*" />

没有任何 <allow-intent> 标签,则不允许向外部 URL 发出任何请求。但是,默认 Cordova 应用程序默认包含一组相当宽松的 allow-intent 条目。建议根据每个应用程序的需求缩小此范围。

在 Android 上,这等同于发送类型为 BROWSEABLE 的意图。

此允许列表仅适用于主 Cordova webview,不适用于任何插件,例如 InAppBrowser webview 或在系统 Web 浏览器中打开链接。它仅适用于 超链接 和对 window.open() 的调用。

注意:allow-navigation 优先于 allow-intent。例如,使用 <allow-navigation href="*" /> 允许导航到所有 URL 会产生“捕获”所有意图的副作用,因此 webview 会导航到这些意图,而不是触发例如外部应用程序。

内容安全策略 (CSP)

控制允许发出哪些网络请求(图像、XHR 等)(通过 webview 直接发出)。

在 Android 和 iOS 上,网络请求允许列表(见上文)无法过滤所有类型的请求(例如,<video> 和 WebSockets 不会被阻止)。因此,除了允许列表之外,您还应该在所有页面上使用 内容安全策略 <meta> 标签。

以下是一些用于您的 .html 页面的示例 CSP 声明

<!-- Good default declaration:
    * https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
    * Disables use of eval() and inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
        * Enable inline JS: add 'unsafe-inline' to default-src
        * Enable eval(): add 'unsafe-eval' to default-src
-->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *">

<!-- Allow everything but only from the same origin and foo.com -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' foo.com">

<!-- This policy allows everything (eg CSS, AJAX, object, frame, media, etc) except that 
    * CSS only from the same origin and inline styles,
    * scripts only from the same origin and inline styles, and eval()
-->
<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">

<!-- Allows XHRs only over HTTPS on the same domain. -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https:">

<!-- Allow iframe to https://cordova.net.cn/ -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; frame-src 'self' https://cordova.net.cn">

其他注意事项

应用程序传输安全 (ATS) 是 iOS 9(Xcode 7)中的新功能。此新功能充当应用程序的允许列表。Cordova CLI 会自动将 <access><allow-navigation> 标签转换为相应的 ATS 指令。

<access><allow-navigation> 标签支持以下三个属性,这些属性在 ATS 中具有等效项

  1. minimum-tls-version(字符串,默认为“TLSv1.2”)
  2. requires-forward-secrecy(布尔值,默认为“true”)
  3. requires-certificate-transparency(布尔值,默认为“false”,iOS 10 中新增)

示例

<access origin='https://cordova.net.cn' minimum-tls-version='TLSv1.1' requires-forward-secrecy='false' requires-certificate-transparency='true' />

在 iOS 10 及更高版本中,当与原点通配符 * 配对时,<access> 标签还支持以下三个属性,如下所述。这些属性在 ATS 中也具有等效项

  1. allows-arbitrary-loads-for-media(布尔值,默认为“false”,iOS 10 中新增。[email protected] 中新增,已修复为使用正确的属性名称)。旧属性 allows-arbitrary-loads-in-media 现在已弃用。
  2. allows-arbitrary-loads-in-web-content(布尔值,默认为“false”,iOS 10 中新增)
  3. allows-local-networking(布尔值,默认为“false”,iOS 10 中新增)

示例

<access origin='*' allows-arbitrary-loads-for-media='true' allows-arbitrary-loads-in-web-content='true' allows-local-networking='true' />

有关更多详细信息,请参阅 ATS 技术说明