水平权限、垂直权限原理及与解决方案

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

认证 (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
水平、垂直权限问题(横向越权与纵向越权)

原文地址 www.jianshu.com