安全
以下指南包含一些在开发 Cordova 应用时应考虑的安全最佳实践。请注意,安全是一个非常复杂的话题,因此本指南并不详尽。如果您认为可以为本指南做出贡献,请随时在 Cordova 的 cordova-docs 存储库中创建拉取请求。本指南旨在适用于一般的 Cordova 开发(所有平台),但会特别指出特定于平台的注意事项。
本指南讨论以下主题
- 允许列表
- 内联框架和回调 ID 机制
- 证书固定
- 自签名证书
- 加密存储
- 一般提示
- 推荐文章和其他资源
允许列表
默认情况下,应用的导航不受限制。建议仅将导航限制在受信任的域。阅读 允许列表指南 了解更多信息。
内联框架和回调 ID 机制
如果内容从允许列表中的域的内联框架中提供,则该域将可以访问本地的 Cordova 桥。这意味着,如果您允许第三方广告网络并通过内联框架提供这些广告,则恶意广告可能会突破内联框架并执行恶意操作。因此,您通常不应使用内联框架,除非您控制托管内联框架内容的服务器。另请注意,有第三方插件可用于支持广告网络。请注意,此说法不适用于 iOS,它会拦截所有内容,包括内联框架连接。
证书固定
Cordova 不支持真正的证书固定。这方面的主要障碍是 Android 中缺乏用于拦截 SSL 连接以执行服务器证书检查的原生 API。(虽然可以使用 Java 在 Android 中使用 JSSE 进行证书固定,但 Android 上的 webview 是用 C++ 编写的,服务器连接由 webview 为您处理,因此无法在那里使用 Java 和 JSSE。)由于 Apache Cordova 旨在跨多个平台提供一致的 API,因此在主要平台中缺少功能会破坏这种一致性。
有一些方法可以近似证书固定,例如在应用程序启动时或应用程序生命周期中的其他不同时间检查服务器的公钥(指纹)是否为预期值。有可用于 Cordova 的第三方插件可以做到这一点。但是,这与在每次连接到服务器时自动验证预期值的真正证书固定不同。
还有一些插件可以为某些平台执行真正的证书固定,假设您的应用程序能够使用该插件执行所有网络请求(即:没有传统的 XHR/AJAX 请求等)。
使用 TLS/SSL
如果您的应用程序与外部服务器通信,则应使用现代加密标准进行通信。尽可能使用 https
协议。
Let's Encrypt 是由非营利组织 Internet Security Research Group 提供的免费、自动和开放的证书颁发机构。Let's Encrypt 将提供免费的标准证书,这对于大多数开发人员来说已经足够了。企业组织可能仍然希望使用提供更多高级功能的传统证书颁发机构,例如 组织验证 证书。
随着时间的推移,安全标准也会发生变化,因此务必及时了解安全标准。今天可能可以接受的 SSL/TLS 配置在未来几年可能不再被接受。应定期使用工具测试您的证书和 SSL/TLS 配置。 SSL Labs 是由 Qualys, Inc 提供的免费在线服务,用于测试您的服务器的 SSL/TLS 配置和加密强度,以及支持的平台。
自签名证书
不建议在您的服务器上使用自签名证书。如果您需要 SSL,则强烈建议您的服务器拥有由知名 CA(证书颁发机构)正确签名的证书。无法进行真正的证书固定使得这一点变得很重要。
原因是,接受自签名证书会绕过证书链验证,这允许任何服务器证书被设备视为有效。这会使通信容易受到中间人攻击。黑客不仅可以轻松拦截和读取设备与服务器之间的所有通信,还可以修改通信。设备永远不会知道这种情况正在发生,因为它不验证服务器的证书是否由受信任的 CA 签名。设备没有证据证明服务器就是它期望的服务器。由于中间人攻击很容易进行,因此接受自签名证书仅比在不受信任的网络上运行 http 而不是 https 好一点。是的,流量将被加密,但它可以使用中间人的密钥进行加密,因此中间人可以访问所有内容,因此加密除了被动观察者之外毫无用处。用户信任 SSL 是安全的,而这将故意使其变得不安全,因此 SSL 的使用会变得误导性。
如果应用程序仅在受信任的网络(例如内部公司网络)中使用。使用自签名证书可能是可以接受的,但是应将公钥预安装在将运行应用程序的设备上。始终优先使用受信任的第三方证书颁发机构。
此处描述的原则不特定于 Apache Cordova,它们适用于所有客户端-服务器通信。
在 Android 上运行 Cordova 时,在应用程序清单中使用 android:debuggable="true"
将允许 SSL 错误,例如自签名证书上的证书链验证错误。因此,您可以在此配置中使用自签名证书,但这不应在应用程序投入生产时使用。它仅用于应用程序开发期间。
加密存储
(待定)
一般提示
不要使用 Android Gingerbread!
- 将您的 min-target-sdk 级别设置为高于 10。API 10 是 Gingerbread,而 Gingerbread 不再受 Google 或设备制造商的支持,因此 Cordova 团队不推荐使用它。
- Gingerbread 被证明是不安全的,并且是最受攻击的移动操作系统之一 https://www.mobilemag.com/2012/11/06/andriod-2-3-gingerbread-security/.
- Android 上的允许列表不适用于 Gingerbread 或更低版本。这意味着攻击者可以在内联框架中加载恶意代码,然后该代码将可以访问所有 Cordova API,并可以使用该访问权限窃取个人数据、向付费号码发送短信以及执行其他恶意行为。
对外部链接使用 InAppBrowser
- 在打开指向任何外部网站的链接时使用 InAppBrowser。这比允许列表中的域名并将内容直接包含在您的应用程序中安全得多,因为 InAppBrowser 将使用原生浏览器的安全功能,并且不会向网站提供访问您的 Cordova 环境的权限。即使您信任第三方网站并将其直接包含在您的应用程序中,该第三方网站也可能链接到恶意网页内容。
验证所有用户输入
- 始终验证您的应用程序接受的任何和所有输入。这包括用户名、密码、日期、上传的媒体等。因为攻击者可以操纵您的 HTML 和 JS 资产(通过反编译您的应用程序或使用 chrome://inspect 等调试工具),因此此验证也应在您的服务器上执行,尤其是在将数据传递给任何后端服务之前。
- 其他应验证数据的来源:用户文档、联系人、推送通知
不要缓存敏感数据
- 如果缓存用户名、密码、地理位置信息和其他敏感数据,则未经授权的用户或应用程序可能会在以后检索到这些数据。
不要使用 eval(),除非您知道自己在做什么
- JavaScript 函数 eval() 有着长期被滥用的历史。不正确地使用它会导致您的代码容易受到注入攻击、调试困难以及代码执行速度变慢。
不要假设您的源代码是安全的
- 由于 Cordova 应用程序是使用打包在原生容器中的 HTML 和 JavaScript 资产构建的,因此您不应认为您的代码是安全的。可以对 Cordova 应用程序进行逆向工程。