本文发表在CCS’15,原文链接:http://www.doc.ic.ac.uk/~cp3213/files/15-ccs-fw.pdf
背景知识
Data disclosure vulnerabilities,数据泄露漏洞,会将某个用户的数据泄露给攻击者,但是这种漏洞难以防御,原因是因为该漏洞绝大多数都是因为程序在逻辑实现上存在问题而造成的漏洞。
现在的Web程序,如WordPress,Drupal都实现了自己的访问控制策略,而且访问控制策略在Web程序中应该是无处不在的,比如如下的Durpal数据库查询操作片段:
在第4行,通过addTag(‘node_access’)对用户的访问权限进行检查。
Data Disclosure漏洞通常可能由以下几种bugs导致:
- Missing check,缺少对资源的检查,如Drupal,CVE-2012-2081
- Avoided check,攻击者可以通过触发避免现有检查的代码路径来访问未经授权的数据,如phpBB,CVE-2010-1627
- Incorrect check,访问控制检查可能没有被正确地实现,这种情况在应用程序的插件中发生的比较多,插件的开发人员可能误解了应用程序的访问控制模型,或是程序的API接口导致了漏洞,比如一个EAR漏洞,仅仅将用户定向到了新的页面,但是程序继续执行,仍旧导致了信息的泄露。
现在在检测Data disclosure漏洞方面存在这么几种方式:
- 程序分析(program analysis),但是这种方式首先需要获得程序的源码,而且绝大多数的工具都只能分析特定的语言。
- 输入校验(input validation),这种方法容易遗漏一些逻辑上的漏洞。
- 异常检测(anomaly detection),分为Execution anomaly detection和Traffic anomaly detection。前者主要关注运行时的程序状态,后者关注网络流量。但是这两种方式首先要定义什么是异常行为,对于许多的web程序,我们其实很难给出关于异常行为的精准定义。
作者发现,诸如WordPress、Drupal、Evernote、phpMyAdmin和phpBB之类的Web应用程序都是基于访问控制列表来决定访问控制策略的:它们将主体(如用户和用户组)与数据对象(如文章、帖子和评论)的访问权限关联起来。这使得只要能够了解访问控制模型的状态,就能使在应用程序之外进行访问控制的校验成为可能。
在本文中,作者提出了使用一个名为FlowWatcher的Web proxy来检测和校验未经授权的数据泄露,proxy会根据对应用程序预期的访问控制策略理解来解释进出应用程序的网络流量。使用HTTP proxy的好处在于:
- 不需要修改应用程序本身或是它们的语言解释器
- 不会对应用程序的performance有什么影响,或者说该影响可以忽略不计
此外,FlowWatcher只关注对数据机密性的威胁,而不是数据的完整性。比如FlowWatcher不能阻止攻击者利用一些漏洞去修改其他用户的数据,因为应用程序可以在后端数据存储中进行更新,而不需要代理知道,只有当数据返回给用户时,代理才能进行介入。
主要挑战
本文主要面对两个挑战:
代理该如何表示应用程序的访问控制策略,并且随着新用户、用户组和数据对象的更新而更新自己的策略(该策略是动态发生变化的)。例如,当属于组G的用户U在WordPress中创建一个新的帖子P时,代理必须将这个新的数据对象P与允许访问它的用户U和组G关联起来。
代理如何通过HTTP请求和响应来有效地跟踪用户数据,以检查违反访问控制策略的行为。
访问控制策略
对于Challege 1,作者提出的解决办法是设计新的_user-data-access(UDA) policy language_,它允许应用程序开发人员将主体(用户或用户组)与允许他们访问的数据对象关联起来,为他们的应用程序指定预期的访问控制模型。
这里需要满足两个要求:
- 因为web proxy只能够获取到client-server的HTTP信息,所以该语言只能使用HTTP请求和响应中包含的信息来表示访问控制策略。访问控制模型中的实体(即要保护的数据对象以及用户和用户组),必须用HTTP请求或是响应中的url和表单等信息来实现web proxy中的访问控制策略。在UDA策略中指的是_definition rules_。
- 该语言必须能够对策略的更改(如访问控制列表或是组成员关系的更新)做出反应来支持访问控制策略的动态演变,因此该语言必须能够将HTTP请求和策略的更新联系起来。在UDADA策略中指的是_update rules_。
UDA policy主要包含两部分内容:实体(Entities)和规则(Rules),先分别介绍下这两部分内容。
实体 Entities
在UDA policy中的实体指的是数据对象(Data objects)和主体(Users and groups)。
- Data objects,一个数据对象o
i包含一些数据项,用D(oi) = _{d1,d2,…}_,是从HTTP请求中提取。以Drupal为例,可以从请求的表单信息中提取出title和body作为数据项来标记一个article数据对象,要求数据项组合能够唯一表示一个数据对象。 - Users and groups,一般来说,当用户通过了身份验证之后的session能够唯一标识一个用户,而对于用户组信息,在HTTP请求中也应该有一个g
i来唯一表示一个用户组。
总而言之,无论是数据对象还是用户或是用户组,都需要对它们进行唯一标识。
规则 Rules
在UDA policy中有两种类型的规则:
- definition/removal rules (+ or -),这种类型的规则主要管理Entities的创建或是删除,即数据对象,用户或是用户组。该规则会提取有关新的Entities的必要信息(这些提取主要都是通过正则表达式匹配),以便将这些新实体添加到访问控制策略中。
- update rules (* or -> or -/>),该规则与访问控制策略的更新有关,例如更新现有的数据对象、在数据对象的访问控制列表中添加允许访问的用户组或禁止某个用户组的用户访问该资源。
每条规则都有一个规则头和规则正文,结构如下图所示:
<type>
:是definition/removal rules还是update rules;
<URL spec>
指的是会触发该条规则的URL;
<constraint>
指的是触发该条规则的其他限制条件;
而rule body中是规则主体,包含一组赋值或映射语句,这些语句将会更新由代理维护的访问控制策略。
对于每个HTTP请求,FlowWatcher会根据规则头(rule preamble)中的内容进行匹配,如果匹配通过则执行规则body中的内容。
以25行的这条规则为例:
该条规则的作用是update rule,如果URL前面有re
关键字,那么就会按照正则规则匹配URL,该条规则还需要满足要求,即存在表单(formfield关键字表示表单),并且表单中的og_private
字段的值为1
。
创建和删除规则
UDA policy会通过definition/revomal rules维护用户、用户组和数据对象的访问控制策略。比如下面这个例子会创建某个用户的访问控制权限:
当用户通过了身份验证之后,HTTP返回的响应(res_hdr)中包含SESSION信息时,就从表单中提取用户名作为id,从Set-Cookie字段中提取出session作为token,Web proxy将利用id和token信息来唯一标识一个用户。
更新规则
Update rules主要有三项任务:
- 更新数据对象,在满足条件时更新该数据对象;
- 更新用户组中的用户,添加或是移除用户;
- 更新数据对象的访问控制列表,通过添加或是移除用户和用户组对该数据资源的访问权限。
符号*
表示更新数据对象,符号->
表示添加用户到用户组或是添加用户/组对某个数据对象的访问控制列表中,符号-/>
表示从用户组中移除某个用户或是将某个用户从某个数据对象的访问控制列表删除。
下图是对数据对象的更新,会根据url匹配对应的数据对象,然后又根据表单中的title和body来更新item:
工具设计
下图用一个例子来说明FlowWatcher的工作步骤:
- Client A发起POST请求,FlowWatcher拦截下该请求(step 1A)
- 根据request请求中的参数和内容更新对应的策略(step 2)
- 将该请求转发给后端服务器(step 3)
- 后端服务器做出响应response,并被FlowWatcher拦截下来(step 4)
- 执行step 2 中的策略来决定该用户是否有访问该数据对象的权限(step 5)
- 如果通过了检查,那么FlowWatcher会将该response放行(step 6A)
- 反之如果Client B的请求(step 1B)中包含Data Disclosure的可能,那么FlowWatcher会对服务器的响应做出改变,移除那部分的数据内容(step 6B)
从上图可以看出,FlowWatcher包含两大操作:
- 执行shadow policy
- 更新shadow policy
Policy执行
FlowWatcher用4个数据结构来存储访问控制状态:
user_auth
将用户映射到他们的tokensgroup_members
将用户映射到他们用户组object_acl
将数据对象映射到具有访问权限的用户/组data_items
将数据对象映射到相关的数据项
如下图所示:
在FlowWatcher将HTTP响应转发给用户之前会检查服务器response的内容是否和shadow UDA policy相符合:
- Indentify requesting user,FlowWatcher会从HTTP请求中提取出authencation token,然后将其与
user_auth
进行比较; - Match response content,FlowWatcher将来自
data_items
的跟踪数据项与响应头和主体匹配 - Check access control list,FlowWatcher会根据
object_acl
查看当前的用户是否具有查看资源的权限 - Consult whitelist,对于没有授权访问的匹配对象,FlowWatcher检查相关数据项D(o
i)是否能在static_data中找到 - Redact response,对于未授权用户UI查看的所有剩余数据对象o
i,FlowWatcher从响应中重新生成数据项D(oi),并提醒系统管理员
Policy更新
下图是一个拥有文章的用户授予新组访问权限时,Flow Watcher如何更新shadow policy的例子:
- FlowWatcher拦截用户的请求(step 1)
- 接着检查请求中的URL或是其他参数,查找被UDA中被触发的definition或是update规则(step 2)
- 接着调用每条被触发的规则(step 3)
- 更新相关的数据结构,如group_members,object_acl或是data_items等
实验评估
FlowWatcher对7种比较流行的Web应用程序进行了测试:
因为这些cms存在一些CVE,所以通过FlowWatcher是否能拦截这些漏洞来证实其有效性。这些CVE的漏洞类型可能不同,如CVE-2010-0287是路径遍历漏洞,CVE-2009-1960是文件包含漏洞,但是最后都导致了数据泄露。
下图是对WordPress生成的访问控制规则:
作者还进行了实验来测量FlowWatcher的运行开销。作者在搭建的Drupal上创建了6000个用户和60个用户组,然后进行登录,访问主页面,添加post,访问post和登出等操作。作者在装有FlowWatcher和不装有FlowWatcher的机器上进行实验,最后发现前者的CPU使用率不会超过10%。
下图Fig 4.表明,FlowWatcher并不会造成额外的开销:
图Fig 5.表明,FlowWatcher也没有什么时延,可以忽略不计:
总结
本文作者设计并实现了一款名为FlowWatcher的web代理工具来防御Data Disclosure漏洞,主要是通过开发者编写UDA策略防御漏洞,有点类似于OpenRASP的waf工具,但是OpenRASP的防御面相对更加的广泛。这要求开发人员对网站的请求信息有充分的了解,不同的应用程序之间的UDA策略很可能不相同。另外UDA策略的一个缺点是,它们依赖于Web应用程序的URL和HTTP请求和响应的特定格式。这意味着如果应用程序更改策略中引用的URL或字段,则必须重新编写UDA策略。而FlowWatcher中的通过定义规则来更新策略的方法还是值得借鉴的。