GBT 22239-2019《信息安全技术 网络安全等级保护基本要求》中,8.1.4.2安全计算环境—访问控制项中要求包括:
a)应对登录的用户分配账户和权限;
b)应重命名或删除默认账户,修改默认账户的默认口令;
c)应及时删除或停用多余的、过期的账户,避免共享账户的存在;
d)应授予管理用户所需的最小权限,实现管理用户的权限分离;
e)应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则;
f)访问控制的粒度应达到主体为用户级或进程级,客体为文件、数据库表级;
g)应对重要主体和客体设置安全标记,并控制主体对有安全标记信息资源的访问。
越权访问对应访问控制项中要求e),所以安全控制点为访问控制e。
GBT 28448-2019《信息安全技术 网络安全等级保护测评要求》中,测评单元(L3-CES1-09)
该测评单元包括以下要求:
a)测评指标:应由授权主体配置访问控制策略,访问控制策略规定主体对客体的访问规则。
b)测评对象:终端和服务器等设备中的操作系统(包括宿主机和虚拟机操作系统)、网络设备(包括虚拟网络设备)、安全设备(包括虚拟安全设备)、移动终端、移动终端管理系统、移动终端管理客户端、业务应用系统、数据库管理系统、中间件和系统附案例软件及系统设计文档等。
c)测评实施包括以下内容:
1)应核查是否由授权主体(如管理用户)负责配置访问控制策略;
2)应核查授权主体是否一句安全策略配置了主体对客体的访问规则;
3)应测试验证用户是否由可越权访问情形。
d)单元判定:如果1)~3)均为肯定,则符合本测评单元指标要求,否则不符合或部分符合本测评单元指标要求。
越权访问漏洞属于测评单元(L3-CES1-09)中测评实施的第3项,故定测评单元为L3-CES1-09.3。
测试系统是否存在特权等级升级到另一个特权等级或同等级其他账户的问题。
越权访问是Web应用程序中一种常见的漏洞,由于其存在范围广、危害大,被OWASP列为Web应用十大安全隐患的第二名。该漏洞是指应用程序在检查授权时存在纰漏,使得攻击者在获得低权限账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。
越权漏洞的成因主要是因为开发人员在后台使用了不合理的校验规则。在对数据进行增、删、改、查时对客户端请求的数据过分相信而遗漏了权限的判定, 一旦权限验证不充分,就易导致越权漏洞。这点与SQL注入漏洞、XSS等漏洞很相像,都是由开发人员对请求的数据没有做到更全的防御导致的风险问题。
一般越权漏洞容易出现在需要验证当前身份的页面,如用户登录、操作数据、提现、修改个人资料、发送私信、上传图片、上传表单、下单、充值、找回密码等处。当用户对权限页面内的信息进行这些操作时,后台需要对当前用户的权限进行校验,看其是否具备操作的权限,从而给出响应,而如果校验的规则过于简单则容易出现越权漏洞。
这类漏洞往往很难通过工具进行自动化检测,属于逻辑漏洞中的一种。越权漏洞一般分为水平越权和垂直越权、交叉越权。
但从广义上来讲还包括一种“未授权漏洞”,这种漏洞类似于越权漏洞的垂直越权,攻击者没有获取到登录权限或未授权的情况下,不需要登录即可通过输入网站控制台地址直接访问进行操作,但此篇文章只讲水平越权与垂直越权,后续会专门写一篇未授权访问漏洞文章。
越权分类
水平越权:
又称横向越权,这是一种“基于数据的访问控制”设计缺陷引起的漏洞。由于服务器端在接收到请求数据进行操作时没有判断数据的所属人/所属部门而导致的越权数据访问漏洞,也就是相同权限的不同用户之间可以互相访问数据以及执行其他用户的功能等。
水平越权
垂直越权:
又称纵向越权,这是一种“基于URL的访问控制”设计缺陷引起的漏洞,由于后台应用没有做权限控制,或仅仅在菜单、按钮上做了权限控制,导致恶意用户只要猜测其他管理页面的URL或者敏感的参数信息,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。也就是低权限用户可访问高权限用户的数据以及执行高权限用户功能等。
垂直越权
交叉越权:
既可以水平越权又可以垂直越权。
以下代码中第8行没有对传入的ID进行校验,ID代表用户,攻击者直接传入指定的ID就可以修改对应用户的个人信息。
// @Tags SysUser// @Summary 设置用户信息// @Security ApiKeyAuth// @accept application/json// @Produce application/json// @Param data body system.SysUser true "ID, 用户名, 昵称, 头像链接"// @Success 200 {string} string "{"success":true,"data":{},"msg":"设置成功"}"// @Router /user/setUserInfo [put]func (b *BaseApi) SetUserInfo(c *gin.Context) { var user system.SysUser _ = c.ShouldBindJSON(&user) if err := utils.Verify(user, utils.IdVerify); err != nil { response.FailWithMessage(err.Error(), c) return } if err, ReqUser := userService.SetUserInfo(user); err != nil { global.GVA_LOG.Error("设置失败!", zap.Error(err)) response.FailWithMessage("设置失败", c) } else { response.OkWithDetailed(gin.H{"userInfo": ReqUser}, "设置成功", c) }}
常用测试思路:
在页面上使用普通账户操作请求。登录用户A时,正常更改或者查看用户A信息,抓取数据包,将传参ID或其他参数修改为其他用户,如果能成功查看或修改了同权限的其他用户信息,就属于水平越权,如果影响到的是高权限用户,就是垂直越权。测试案例1通过身份信息伪造进行水平越权。
还有种情况是身份控制参数直接出现在URL中,对此就可直接遍历URL中的参数值获取其他用户的信息。
修复:
身份信息必须进行加密传输,要采取标准的加密方式进行加密,并保存好密码,尽量不要使用base64编码等非强加密算法,即使使用base64传输,也需要加入脏数据进行混淆,增加破解难度。
出现此漏洞的原因是,源码中没有判断用户身份,需要添加一段判断get请求是否来自lili(也就是当前登录的用户)的代码,拒绝越权的尝试。
修复:
在每个步骤的session都应该添加标识位,并将session与用户的身份进行强绑定,并在新步骤显示之前必须要检测之前每一步的session标志位。
关于密码修改的地方还可以使用一次性填写所有的校验信息,例如原始密码、新密码等信息后再提交/重置密码请求。
下载地址:https://github.com/portswigger/authz使用方法:https://gh0st.cn/archives/2019-06-27/1?hmsr=toutiao.io&utm_campaign=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
平时做测试发现越权漏洞大多是基于修改ID的方式:将A用户的ID改成B的ID,然后进行请求查看是否可以越权获取到信息,或当ID的规律已知情况下基于Burp Intruder模块直接去遍历ID。
而基于Authz的检测是不一样的,它是将用户认证的HTTP请求头进行修改(Cookie之类的),然后通过响应长度、响应状态码判断是否存在越权;
从本质上来讲没有任何区别,只是换了一个角度,但这样的好处是一定程度上的减少了测试的时间(例如:一个商城的业务系统,你有A、B账户,A账户买了个商品获得一个订单信息请求,当你想测试是否能越权获取B账户订单时就需要使用B账户去再购买,然后判断测试。)
优点:使用简单、省时省力;
缺点:只适用于检测越权读取类的操作,删除编辑类操作还需要人工判断。
下载地址:https://github.com/ztosec/secscan-authcheck
secscan-authcheck工具比较强大,安装也比较麻烦,需要搭建自己的服务器,将工具安装在服务器上,然后需要在浏览器安装插件,将浏览器访问流量导入自己的服务器上,使用该工具检测是否有越权漏洞。
用户可以操作比自己高权限用户操作范围的数据(如管理员账号),具体危害与对应业务的重要性相关。
不同的用户应该拥有不同的权限去做增删改查等操作,恶意攻击者可利用该漏洞去越权查看、修改其他用户的敏感信息,对账户安全造成威胁
越权漏洞的本质就是访问到当前用户本不该访问的页面、执行不该执行的操作,所以对用户的权限验证尤为重要。
1. 完善安全架构、用户权限体系。知道哪些数据对应哪些用户,哪些数据不应该由哪些用户操作;
2. 鉴权,服务端对请求的数据和当前用户身份做校验;
3. 不要直接使用对象的实名或关键字,例如订单ID使用随机数;
4. 对于用户访问角色的权限进行严格的检查及限制,前后端同时对用户输入信息进行校验,双重验证机制;
5. 在一些操作时可以使用session对用户的身份进行判断和控制;
6. 调用功能前验证用户是否有权限调用相关功能;
7. 执行关键操作前必须验证用户身份,验证用户是否具备操作数据的权限;
8. 直接引用对象的加密资源ID,防止攻击者枚举ID,敏感数据特殊化处理;
9. 永远不要相信来自用户的输入,对于可控参数进行严格的检查与过滤;
很赞哦! (119)