【OWASP TOP 10】TOP4-不安全的直接对象引用 详解与进攻实验

34

描述

一个已经授权的用户,通过更改访问的一个参数,从而访问到原本其没有得到授权的对象。Web应用往往在生成Web页面时会用它的真实名字,且不会对所有的目标对象访问时来检查用户权限,所以这就造成不安全的对象直接引用的漏洞。

我们看如下一个示例

  1. 攻击者发现他自己的参数时6666,即?acct=6666
  2. 他可以直接更改参数为8888,即?acct=8888
  3. 这样他就可以直接看到8888用户的账户信息

危害

这种漏洞能破坏通过该参数引用的所有数据。除非对象引用是不可预知的,否则攻击者很容易访问该类型的所有数据。


简单漏洞例子

应用程序在访问帐户信息的SQL调用中使用未验证数据:

1
2
3
4
String query = "SELECT * FROM accts WHERE account = ?";
PreparedStatement pstmt =connection.prepareStatement(query , …);
pstmt.setString(1, request.getparameter("acct"));
ResultSet results = pstmt.executeQuery();

攻击者能轻易在浏览器将“acct”参数修改成他所想要的任何账户号码。如应用程序没有进行恰当的验证,攻击者就能访问任何用户的账户,而不仅仅该目标用户的账户。

http://example.com/app/accountInfo?acct=notmyacct


初次进攻实验

现在我们准备通过一个电影购票网站来在线订购电影票,示例网站地址为 bookmyshow.com,这个网站中存在不安全的直接对象引用漏洞。

在这个网站中,我打算订购十张电影票,每张票的加个为十五欧元。接下来,我们确认订单,然后使用BurpSuite来捕捉浏览器请求。

2

捕获到的请求如下图所示,高亮部分包含了需要订购的电影票数量、每张票的价格(十五欧元)以及订单类型。接下来,我们就要尝试修改订单金额,将加个修改成我们想要的价格:

3

我将单张票价修改为了一欧元,这也就意味着我只需要花十欧元就能买十张票了。下图中显示了请求信息:

4

没错,我们成功地用十欧元购买了十张电影票!


防守方案

要防止不安全的直接对象引用,需要选择一个适当的方法来保护每一个用户可访问的对象(如对象号码、文件名):

  • 使用基于用户或者会话的间接对象引用。这样能防止攻击者直接攻击未授权资源。例如,一个下拉列表包含6个授权给当前用户的资源,它可以使用数字1-6来指示哪个是用户选择的值,而不是使用资源的数据库关键字来表示在服务器端,应用程序需要将每个用户的间接引用映射到实际的数据库关键字。OWASP的ESAPI包含了两种序列和随机访问引用映射,开发人员可以用来消除直接对象引用。
  • 检查访问。任何来自不可信源的直接对象引用都必须通过访问控制检测,确保该用户对请求的对象有访问权限。

参考来源