安全指南

以下的指南包含了一些在你创建Cordova应用的时候需要考虑的一些安全最佳实践。你要意识到安全问题是一个非常复杂的问题,因此这篇指南也不能详尽的阐明。如果你觉得你可以为这篇指南做出贡献,请在"Documentation"下面的Cordova问题追踪里提出你的问题。这篇指南对常规的Cordova开发(所有平台)都适用,一些特定平台的注意事项会标注出来。

这篇指南主要讨论以下的主题:

  • 白名单
  • iframe和回调ID机制
  • 证书锁定
  • 自签名证书
  • 加密存储
  • 建议
  • 推荐文章和其他资源

白名单

  • 阅读和理解白名单指南

  • 域名白名单不支持Android API 10及以下,也不支持WP8中的iframe和XMLHttpRequest。这意味着攻击者可以在iframe里加载任何域名,可以通过iframe在页面上加载任何脚本,从而直接访问Cordova的JavaScript对象和相应的native Java对象。为这些平台创建应用的时候,你需要考虑到这个问题。实践中你最好保证你的用户的Android API版本高于10,如果可能的话不要使用iframe来加载外部内容 - 使用inAppBrowser插件或者其他第三方插件替代。

iframe和回调ID机制

如果内容是通过iframe由一个白名单内的域名提供的,那么这个域名就会访问native和Cordova之间的桥梁。这意味着如果你把一个第三方的广告网络加入了白名单并且通过iframe来提供广告服务,那么很有可能会有恶意广告突破iframe来执行恶意操作。正因为如此,一般情况下不要使用iframe,除非你控制了那台生产内容的服务器。也要了解已经有第三方插件可以支持广告网络。注意:这条声明对IOS不成立,他会拦截所有包括iframe在内的连接。

证书锁定

Cordova不支持证书锁定,主要的障碍是Android缺少原生API去拦截SSL连接然后执行服务器认证。(尽管在Java JSSE中可以实现证书锁定,但是Android的webview是C++编写的,而且是Webview处理服务器连接的,所以在Android中不能使用Java JSSE。)因为Apache Cordova旨在提供跨多平台的一致的API,所以不会在一个主要平台上打破一致性。

有一些方法可以提供近似的证书锁定效果,例如在程序启动的时候或者在程序生命周期的任意时间段检查服务器的公钥(指纹)。一些Cordova的第三方插件可以实现。但是,这和真正的证书锁定还是不一样的,真正的证书锁定会自动验证每次连接的证书是否正确。

同样还有一些插件在特定平台上可以做到真正的证书锁定,通过这个插件你的app可以处理所有的网络请求(除了传统的XHR/AJAX等请求)验证。

自签名证书

不建议在你的服务器中使用自签名证书。如果你想用SSL,那么强烈推荐你在知名的CA(认证授权机构)给你的服务器注册证书。不能实现证书锁定的话,那注册证书就很重要。

原因是,接受自签名证书意味着绕过证书连锁验证,会让设备认为任何证书都是合法的。这可能导致中间人攻击。会让黑客很容易截断并获取甚至修改设备和服务器之间的通信内容。设备永远不会知道攻击的发生,因为它不会验证服务器的证书是否是可信的认证授权机构颁发的,它没有证据证明这个服务器是它所期望的。正因为实现中间人攻击如此简单,接受自签名证书只比在一个不受信任的网络中使用http代替https好一点点。是的,传输会被加密,但是它可能是用从中间人获取的key来加密的,然后中间人就可以访问他想访问的一切,所以加密是无用的除非是对于被动的观察者。用户相信SSL是安全的,而加密的问题会让SSL不再安全,所以SSL的使用反而变成了误导。如果SSL被用在可信任的网络中(换句话说,你完全处在一个受控制的企业网络里),然而自签名证书还是不推荐的。在可信任的网络中两条推荐的建议一是使用http,因为网络自身是可信任的;二是获取可信任的CA认证的证书(不是自签名的),不管网络是可信任的还是不可信任的。

这里描述的原则不仅仅是针对Apache Cordova,而是对所有的客户端和服务器之间的通信都适用。

当在Android中运行Cordova时,如果在程序清单中使用'android:debuggable="true"',程序就会允许SSL错误,例如自签名证书中的证书连锁验证错误。所以通过这个配置你就可以使用自签名证书,但是这个配置不能在生产环境中使用。这也意味着自签名证书只能在应用开发阶段使用。

加密存储

(TBD)

建议

不要使用Android Gingerbread(Android2.3版本)!

  • 保证你的SDK版本大于10。API 10是安卓2.3的,谷歌和设备制造商已经不给安卓2.3提供支持,因此Cordova小组不建议使用它。
  • Android2.3是不安全的,而且已经被列为最不安全的手机系统之一http://www.mobilemag.com/2012/11/06/andriod-2-3-gingerbread-security/
  • 白名单不支持Android2.3及以下版本。这意味着攻击者可以在iframe里加载恶意代码,然后通过调用Cordova的API,窃取用户资料,发送短信给高收费的号码,或执行其他恶意攻击。

使用app内置浏览器打开外链

  • 使用app内置浏览器打开外部链接。这比给一个域名添加白名单然后直接在app内获取内容更简单,因为app内置浏览器会使用原生浏览器的安全特性,而且不会让你的Cordova环境被外部访问到。即使你信任第三方的网站并把它直接包含在你的应用里,但这个第三方网站还是有可能指向恶意的网络内容。

校验所有的用户输入

  • 永远要校验应用要接收的所有输入,包括用户名,密码,时间日期,上传文件等。因为攻击者可以篡改你的HTML和JavaScript资源(反编译程序或者使用chrome://inspect之类的调试工具)。服务端同样需要验证输入,特别是在传递数据到后台服务之前。
  • 需要验证的其他来源:用户文档,联系人,推送的通知。

不要缓存敏感信息

  • 如果用户名、密码、定位信息或者其他一些敏感数据被缓存了,那么这些数据很有可能会被未授权的用户或者应用获取到。

不要使用eval()除非你知道你自己正在做什么

  • JavaScript的eval()有很长的滥用历史。如果使用的不正确会把你的代码暴露给注入式攻击,而且难以调试,减慢代码的执行速度。

不要假设你的源代码是安全的

  • 因为Cordova应用是由HTML和JavaScript资源在native容器里打包而成的,你不能认为你的代码是安全的。反编译Cordova程序也是可能的。

推荐文章和其他资源