当前位置:首页 > 焦点

权限许可和访问控制漏洞

去年某天凌晨,权限我盯着服务器日志里一行奇怪的和访请求记录,一个普通注册用户竟然调用了管理员才有的问控删除接口,把测试环境里三十多条订单数据清空了。制漏问题出在哪?权限代码里那个接口只在前端做了按钮隐藏,后端压根没校验用户角色。和访这种低级错误每年都在大量系统里重复上演。问控

权限许可和访问控制这摊子事,制漏说白了就是权限回答两个问题:你是谁,你能干什么。和访听起来简单,问控做起来漏洞百出。制漏我见过太多开发把权限校验写成if (user.isAdmin)就完事,权限结果普通用户改个请求参数就能绕过。和访还有的问控系统把权限判断散落在几十个文件里,改一条规则要翻半天代码,漏掉一处就是洞。

最常见的坑是“前端校验等于没校验”。浏览器里F12一按,隐藏的按钮、禁用的输入框全都能改回来。有人觉得普通用户不会这么干,但攻击者会。我之前参与过一次渗透测试,目标系统后台管理页面在前端路由里做了角色判断,非管理员访问直接跳转404。听起来还行?我直接拿普通账号的token去请求管理接口,服务器照常返回数据。前端跳转根本不代表后端拒绝。

另一个高频问题是水平越权。用户A能看自己的订单,改一下订单ID就能看用户B的。这类漏洞比垂直越权更隐蔽,因为功能本身是正常的,只是没校验资源归属。我审计过一个电商项目,查询订单详情的SQL是SELECT * FROM orders WHERE id = ?,没带用户ID条件。攻击者写个脚本遍历订单ID,能把全站订单拖下来。修复也简单,加个AND user_id = ?就行,但就是没人加。

权限模型设计本身也容易出问题。RBAC(基于角色的访问控制)用得多,但角色爆炸是常态。一个中型系统跑两年,角色表里躺着两百多个角色,有些名字叫role_temp_2023_test,没人知道谁该用。更麻烦的是角色继承关系混乱,A角色继承B,B又继承C,C不小心给了个删除权限,整条链上的人都拿到了。我倾向于把权限粒度做细,直接绑到具体操作上,角色只是权限的集合,别搞太深的继承树。

访问控制还有一类容易被忽略的场景:API之间的调用。微服务架构下,服务A调服务B,通常用内部token或者mTLS。但有些团队图省事,内部接口不鉴权,觉得“内网就是安全的”。一旦攻击者拿下边缘服务,就能在内网横向移动,调用任意内部接口。零信任那套东西听着烦,但“内网不等于可信”这条得刻在脑子里。

说个具体的修复思路。权限校验必须放在后端每个需要保护的入口处,别依赖前端。资源归属校验要跟业务查询绑在一起,别先查出来再在代码里判断——那样容易漏。权限模型尽量扁平,角色别超过两层继承。内部服务调用也要带身份,别裸奔。最后,写单元测试的时候别只测正常流程,拿低权限账号去调高权限接口,断言返回403。这比事后打补丁便宜多了。

我见过最离谱的一个案例:某系统用URL路径做权限控制,/admin/*需要管理员。结果攻击者用/Admin/deleteUser就绕过了,因为路由匹配大小写不敏感,但权限拦截器用的是字符串前缀匹配,区分大小写。这种细节上的不一致,比没做权限还危险,因为它给人一种“已经做了”的错觉。

权限这玩意儿,不怕做得糙,就怕做得半吊子。要么别做,要么每个入口都老老实实查一遍。省那几行代码的时间,后面得用几天来擦屁股。

分享到: