允许列表

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

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

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

网络请求允许列表

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

这控制着允许对特定域(通过 Cordova 原生钩子)进行哪些网络请求(图像、XHR 等)。

注意:建议使用 内容安全策略 (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> 标签,则只允许对 file:// URL 的请求。但是,默认的 Cordova 应用默认包含 <access origin="*">

注意:允许列表无法阻止从允许列表中的远程网站(即 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,您必须在 config.xml 中添加 <allow-navigation> 标签

<!-- 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 或在系统网络浏览器中打开链接。它只适用于 超链接 和对 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 技术说明