详解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引发的安全漏洞还是相对隐蔽的,因为并不是我们的主动行为。以上内容如有错误纰漏,欢迎指正。


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

查看所有标签

猜你喜欢:

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

安全测试指南(第4版)

安全测试指南(第4版)

OWASP基金会 / 电子工业出版社 / 2016-7-1 / CNY 89.00

软件安全问题也许是这个时代面临的*为重要的技术挑战。Web应用程序让业务、社交等网络活动飞速发展,这同时也加剧了它们对软件安全的要求。我们急需建立一个强大的方法来编写和保护我们的互联网、Web应用程序和数据,并基于工程和科学的原则,用一致的、可重复的和定义的方法来测试软件安全问题。本书正是实现这个目标的重要一步,作为一本安全测试指南,详细讲解了Web应用测试的“4W1H”,即“什么是测试”、“为什......一起来看看 《安全测试指南(第4版)》 这本书的介绍吧!

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

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码