整理水平、垂直权限遇到的问题与解决方案

在谈水平权限和垂直权限设计之前需要清楚以下几个概念。

权限: 其实主要是针对用户和管理员这两大类角色的操作,这是一种赋予的能力,对权限进行合理分配与设计,是安全设计的核心。

认证(Authentication): 认证的目的是为了 认出用户是什么人?或者说角色,能够解决我是谁的问题。

授权(Authorization):顾名思义,是为了让用户能够做什么的操作,授予用户权限。

系统对某个用户需要进行哪些操作,对这些操作的控制就是权限控制。在一个安全的系统中,通过认证来确认主体的身份。客体是一种资源,是主体发起请求的对象。主体所能做什么,就是权限,权限可以细分为不同的能力,例如:在Linux文件系统中,将权限分为 读、写、执行 三种能力。"基于角色的访问控制"和"基于数据的访问控制"是进行系统安全设计时经常用到的两种控制方式。

垂直权限(功能权限)

访问控制是建立用户与权限之间的关系,目前常用的一种是基于RBAC模型,也称为垂直权限。也就是用户之间所属的角色的权限没有交互。

例如: 在一个论坛中,有admin、普通用户、匿名用户三种角色,admin有删除、编辑、置顶帖子的权限,普通用户有评论和浏览帖子的权限,匿名用户只有浏览帖子的权限。目前已有 Shiro,Spring Security 等基于 RBAC 模型的成熟框架来处理功能权限管理和鉴权的问题。

垂直权限的漏洞举例:Web应用程序在服务端没有做权限控制,只是在前端菜单显示上将部分页面隐藏了。此时,恶意用户可以猜测其他管理页面的 URL,就可以访问或控制其他角色拥有的数据或页面,达到越权操作的目的,可能会使得普通用户拥有了管理员的权限。

垂直权限漏洞是指Web应用没有做权限控制,或仅仅在菜单上做了权限控制,导致恶意用户只要猜到了其他页面的URL,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。

解决:对管理员所见的管理界面 URL,每次用户访问时,都要判定该用户是否有访问此 URL 的权限。推荐使用成熟的权限解决方案框架。

水平权限

用户A和用户B可能同属于一个角色 RoleX,但用户 A 和用户 B 都各自有一些私有数据,正常情况下,用户自己只能访问自己的私有数据,例如:你有删除邮件的功能(操作权限),但只能删除自己的邮件,不能误删其他人的邮件(数据权限)。但在 RBAC 模型下,系统只会验证用户A是否属于角色 RoleX,而不会判断用户A是否能访问只属于用户B的数据 DataB,此时就可能发生越权访问。

这种问题,称之为『水平权限管理问题』,又可以称之为『基于数据的访问控制』:相比垂直权限管理来说,水平权限问题出现在同一个角色上,系统只验证了能访问数据的角色,没有对数据的子集做细分,因此缺乏了一个用户到数据级之间的对应关系。对于数据的访问控制,与业务结合的比较紧密,目前还没有统一的数据级权限管理框架,一般是具体问题具体解决。


数据权限就是控制访问数据的可见范围,表现形式是:当某用户有操作权限时候,不代表对所有数据都有查看或管理的权限。一般表现为行权限和列权限:

行权限:限制用户对某些行的访问,例如:只能对某人、某部门的数据进行访问;也可以是根据数据的范围进行限制,例如:按合同额大小限制用户对数据的访问

列权限:限制用户对某些列的访问,例如:某些内容的摘要可以被查阅,但详细内容只有 VIP 用户能查阅

水平权限的漏洞案例:Web应用程序接受用户的请求,修改某条数据id(资源的唯一编号)时,而没有判断当前用户是否可以访问该条记录,导致恶意用户可以修改本不属于自己的数据。例如:/api/v1/blog?blogId=xxx [DELETE] 这是删除博客内容的url,当用户改变 blogId 时,后端如果未校验博客的所属人是否是当前用户,则可以删除其他人的博客内容。

解决方案:

用户做出相应动作时(新建、删除、更新等)时,需要对其会话身份进行验证(可采用Cookie机制),并且对用户访问的对象记录校验数据权限是否ok(按业务场景)。

水平权限参数不要用自增值,用id加密、随机数或GUID,但搜索引擎或攻击者可以同样用这个随机数和连接去进行操作

web层检查发起请求的用户权限,比如从session信息中获取

数据库表增加ownerId字段,增删改查询时加上其作为where语句条件(即每一个信息增加一个发布人的字段,修改的人必须与发布的人为同一个人才可以访问)

横向越权与纵向越权

横向越权:横向越权指的是攻击者尝试访问与他拥有相同权限的用户的资源
纵向越权:纵向越权指的是一个低级别攻击者尝试访问高级别用户的资源

如何防止横向越权漏洞:

可通过建立用户和可操作资源的绑定关系,用户对任何资源进行操作时,通过该绑定关系确保该资源是属于该用户所有的。对请求中的关键参数进行间接映射,避免使用原始关键参数名,比如使用索引1代替id值123等

如何防止纵向越权漏洞:

建议使用基于角色访问控制机制来防止纵向越权攻击,即预先定义不同的权限角色,为每个角色分配不同的权限,每个用户都属于特定的角色,即拥有固定的权限,当用户执行某个动作或产生某种行为时,通过用户所在的角色判定该动作或者行为是否允许。

参考:
权限控制和OAuth
水平、垂直权限问题(横向越权与纵向越权)

你可能感兴趣的:(整理水平、垂直权限遇到的问题与解决方案)