详解NSURLCache缓存引发的安全漏洞

栏目: 编程工具 · 发布时间: 5年前

内容简介:最近项目App交付第三方安全机构进行安全检测,暴露出了一个安全漏洞,具体表现为在沙盒里面检测到了交易登录账号和密码明文(HTTPS接口),如果手机被盗丢失就有可能被破解获取到(虽然手机被盗丢失概率甚微再加上密码破解、越狱等一系列操作难度也甚大,但作为一名程序猿我们还是得从理论上来避免不是)。刚看到报告的时候,第一时间是有点诧异的,因为从来就没主动保存过密码,后来发现原来是NSURLCache引起的。NSURLCache将NSURLRequest和NSCachedURLResponse一一映射起来,配合NSU

最近项目App交付第三方安全机构进行安全检测,暴露出了一个安全漏洞,具体表现为在沙盒里面检测到了交易登录账号和密码明文(HTTPS接口),如果手机被盗丢失就有可能被破解获取到(虽然手机被盗丢失概率甚微再加上密码破解、越狱等一系列操作难度也甚大,但作为一名程序猿我们还是得从理论上来避免不是)。刚看到报告的时候,第一时间是有点诧异的,因为从来就没主动保存过密码,后来发现原来是NSURLCache引起的。

NSURLCache

NSURLCache将NSURLRequest和NSCachedURLResponse一一映射起来,配合NSURLRequestCachePolicy,iOS将为你建立了一套完整的HTTP缓存机制。NSURLRequestCachePolicy相信大家都很熟悉,这里不多说。NSURLCache同时提供了内存和磁盘的缓存,我们可以自定义缓存的大小;磁盘缓存路径默认为沙盒Library/Caches/{bundle id}/Cache.db,当然 我们也是可以自定义缓存路径的。

存储数据库

NSURLCache最终以数据库的形式存储数据,我们打开Cache.db一探究竟。我们只需关注下图的三个表:

详解NSURLCache缓存引发的安全漏洞
  • cfurl_cache_response,包含了request_key字段,也就是我们请求的url,如下图:
    详解NSURLCache缓存引发的安全漏洞
    看到我在测试环境下的登录接口是http://***/login(https表现一样),同时还包含了一个主键entry_ID。
  • cfurl_cache_receiver_data,包含了服务端返回的数据,我们根据上图entry_ID查找,数据如下图:
    详解NSURLCache缓存引发的安全漏洞
  • cfurl_cache_blob_data, 包含了请求和响应数据,格式为blob,如下图:
    详解NSURLCache缓存引发的安全漏洞
    我们将其保存成文本,然后命令行cat即可查看到里面包含了请求的参数,如下图为登录的账号和密码:
    详解NSURLCache缓存引发的安全漏洞
    同时我们看到文件内容以bplist00开头,其实它就是一个plist文件。

删除缓存

好了,至此我们已经定位到了账号密码的缓存所在,为安全起见,必须将其删除掉。查一下API文档,NSURLCache提供了以下两个针对特定请求删除缓存的接口,那么我们顺理成章地调用它们不就把缓存解决掉了吗?事与愿违地是,经调用测试发现这两个接口都是无效的,并不能把对应的缓存删除掉,具体得等苹果爸爸在后续哪个版本修复了:

- removeCachedResponseForRequest:
    Removes the cached URL response for a specified URL request.
- removeCachedResponseForDataTask:
    Removes the cached URL response for a specified data task.
复制代码

此外,还有两个接口可以删除缓存,不过并不能做到针对具体请求,所以并不满足我们的需求。

- removeCachedResponsesSinceDate:
    Clears the given cache of any cached responses since the provided date.
- removeAllCachedResponses
    Clears the receiver’s cache, removing all stored cached URL responses.
复制代码

删除缓存的方案宣告失败。

Cache-Control

转而一想,HTTP头部有个Cache-Control字段,我们何不利用它来管理缓存的存储方案呢? Cache-Control对应请求和响应又有不同的值,主要包括以下:

  • 请求指令:
字段 说明
max-age=<seconds> 设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间
max-stale[=<seconds>] 表明客户端愿意接收一个已经过期的资源。 可选的设置一个时间(单位秒),表示响应不能超过的过时时间。
min-fresh=<seconds> 表示客户端希望在指定的时间内获取最新的响应。
no-cache 在释放缓存副本之前,强制高速缓存将请求提交给原始服务器进行验证。
no-store 缓存不应存储有关客户端请求或服务器响应的任何内容。
no-transform 不得对资源进行转换或转变。Content-Encoding, Content-Range, Content-Type等HTTP头不能由代理修改。例如,非透明代理可以对图像格式进行转换,以便节省缓存空间或者减少缓慢链路上的流量。 no-transform指令不允许这样做。
only-if-cached 表明客户端只接受已缓存的响应,并且不要向原始服务器检查是否有更新的拷贝
  • 响应指令:
字段 说明
must-revalidate 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
no-cache 在释放缓存副本之前,强制高速缓存将请求提交给原始服务器进行验证。
no-store 缓存不应存储有关客户端请求或服务器响应的任何内容。
no-transform
public 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
private 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它),可以缓存响应内容。
proxy-revalidate 与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略。
max-age=<seconds> 设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间
s-maxage=<seconds> 覆盖max-age 或者 Expires 头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略。

这里我们只要针对该请求或者服务端响应设置no-store值,客户端NSURLCache就不会对其进行缓存,问题得以完美解决。

小结

涉及到安全的问题还是得慎重严谨处理为上,关于此次NSURLCache引发的安全漏洞还是相对隐蔽的,因为并不是我们的主动行为。以上内容如有错误纰漏,欢迎指正。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ActionScript 3.0 Cookbook

ActionScript 3.0 Cookbook

Joey Lott、Darron Schall、Keith Peters / Adobe Dev Library / 2006-10-11 / GBP 28.50

Well before Ajax and Microsoft's Windows Presentation Foundation hit the scene, Macromedia offered the first method for building web pages with the responsiveness and functionality of desktop programs......一起来看看 《ActionScript 3.0 Cookbook》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具