其他分享
首页 > 其他分享> > 应用安全系列之二十二:授权问题

应用安全系列之二十二:授权问题

作者:互联网

     权限管理是一个系统的比较核心的安全模块,如果没有正确的权限管理,由权限问题导致的问题基本上都是比较严重的问题,而且带来的危害也很严重,更为重要的是,权限的安全问题很容易被利用而且比较难于监测。

        权限问题主要分为两种:水平越权和垂直越权。

        1 水平越权

        水平越权是指同一个角色的不同人员都有各自的私有信息和资源,特别是私有信息,在信息安全越来越被关注的当代,这些信息对用户也越来越重要,如果授权控制不当,导致用户的私有信息泄露,对产品的影响会很大,特别是有名的网站或者产品,例如,FaceBook曾经出现过因为授权问题而导致的客户的隐私泄密,受到业界的关注和报道,影响非常大。

        下面的代码是一个水平越权的例子:

         http://www.xxxx.com/mblog/delete.php?userID=98522&blogID=5843258546&rnd=0.6

         实现代码如下:

String userIDInRequest = reqest.getParameter("userID");
String userIDInSession = request.getTokeyKeyValue("userID");

if (userIDInSession.equalsIgnoreCase(userIDInRequest))
{
	DeleteBlog(request.getParameter("blogID"));
	
    // 处理删除博客后,页面的显示
}

        这段代码的问题就出在if判断语句上,因为只要一个正常的用户登录,会话中的userID和请求中发的userID应该都是一样的,这就导致了,只要你登录,你就可以通过修改参数中的额blogID来删除任何用户的博客。如果一个攻击者注册一个用户,并且使用自动化工具尝试去删除博客,会对系统带来灾难性的后果,而且,很难恢复被删除的数据。

        2 垂直越权

        垂直越权就是指在不同的角色或者级别的用户之间,一个角色或者级别的用户可以访问另外一个角色或者级别的用户的资源或者信息。它既包括向上提权,也包括向下越权。向上提权,这个都很容易理解,可能有的人会问:“既然越权,怎么还有向下越权的行为呢?”一个高级别的用户或者权限更高的角色,应该可以访问级别或者权限相对较低的角色的资源和信息,听起来,这好像很合情合理。但是,在实际的应用中,却不可以,因为,每一个用户(即使级别再低)都有他自己的私有的敏感信息,例如:年龄、信用卡号等。他希望这些信息只有他自己知道,不希望其他的任何人员知道,即使是系统的管理员。有的网站在用户注册的时候,也提供选择项让用户选择是否公开他的一些注册的信息,如果选择不公开的话,那么,任何人都不应该随便可以看到他的信息。所以,向下越权也需要被关注和预防。尤其是,最近几年也经常有内部用户的“内鬼”通过贩卖数据获取利益,所以,即使是内部系统的正常用户,也需要考虑是否需要给与他最小权限。

        容易导致垂直越权的原因有两种:

        1) 用户的角色通过客户端传递,容易被篡改

        有些人在设计系统时为了方便,把角色传递到客户端,以参数或者Cookie的形式再传送回来,通过传送的数据来判断用户是什么角色,具备什么权限。如果角色的参数没有使用加密算法保护,攻击者就可以修改请求中的角色信息,获取更高的权限。例如:

https://www.test.com/delUser.do?userID=111111&role=normal

虽然实际的代码实现中没有这么直接的实现方法,但是,这里只是以它作为例子来说明,其实放到参数、Cookie或者Form表单里等,都是很容易被篡改,可能没有URL参数这么直接。这里,通过修改role的值为admin,就可以获取管理员的权限删除指定的用户。

        2) 服务器端没有检查发送请求的用户的角色与权限

        有些系统虽然没有服务器和客户端之间传递角色信息,但是,在服务器端没有采用统一的权限处理框架来处理,导致某些URL或者所有URL都没有真正判断权限,所有的权限判断完全是通过客户端是否显示某些菜单或者按钮来控制的。虽然这可以限制正常的用户,但是,这对于攻击者来说,没有任何挑战,通过爬虫获取相关的URL,然后就可以通过工具直接组装相关URL的请求,这样,攻击者也很容易获取其他角色的权限。

        在做过一个网站的渗透测试,通过两个角色的菜单对比,发现很多功能一般角色没有权限,但是通过代理工具截获管理员的特殊功能的URL,直接在一般用户登录的浏览器里面直接访问,居然也可以。更为严重的是,当一般用户访问用户列表的页面时,居然,把用户的密码已明文的形式显示在密码输入框里,虽然显示的是*,但是通过修改输入框的属性,就可以将密码直接显示出来。通过代理工具拦截响应消息,可以获取所有用户的密码。更是有的系统,针对一些关键的含有敏感信息的页面居然没有任何权限控制,甚至是是否登录的验证,直接可以在没有登录的情况下,直接访问内部的含有敏感信息的页面。

        曾经针对一个使用SpringMVC框架构建的系统做代码审计时,发现有的action有权限验证的注解,有些action压根就没有,甚至没有是否登录的验证。经过确认才知道,没有做权限和认证验证的action是内部的go语言写的服务交互的,不对外开放。但是,有没有指定防火墙规则控制那些可以外部访问,那些可以内部访问,导致这些只限内部访问的功能,实际上是对外业开放的,任何人在不登录的情况下,也可以访问。所以,在设计系统时,内部API和外部API都需要有一个明显的区分方法,以便可以统一指定规则控制。

        针对权限控制的问题,其实预防起来也很简单:

        1) 利用框架的访问控制机制或者根据其改进的符合产品的访问控制机制,针对所有API都要进行分析并且明确地规定哪些角色可以访问,即使是对外公开的API,也需要统一管理。

        2)针对内外API,需要明确区分它们,并且使用不同的访问控制机制控制每一个API。

        3)不相信客户端发送的任何信息,针对每一次请求,都要严格验证。

        4) 尽量使用集中授权管理,不要分散授权,分散授权容易导致授权的不一致。

        5) 无论如何需要记住最小权限原则,在非必要的情况下,不要授予一个用户或者角色过多的权限。

        6) 关键操作或者对系统数据有修改的操作,都需要记录日志。一旦有了意外的恶意操作,可以通过日志检测到,可以主动及时修改系统,弥补系统的漏洞。

        总之,访问控制管理的目的就是:确保被授权的用户能够在自己的权限范围内做被允许的操作,除此之外,所有其他操作都不会被允许,一旦有异常操作,也需要及时检测。        

标签:二十二,系列,或者,角色,用户,信息,授权,权限,越权
来源: https://blog.csdn.net/jimmyleeee/article/details/118632872