小知识分享:控制层尽量别暴露这样的接口,避免横向越权。

发布时间 2023-09-09 18:54:41作者: 程序员济癫

前言

谈不上是多么厉害的知识,但可能确实有人不清楚或没见过。

我还是分享一下,就当一个小知识点。

如果知道的,就随便逛逛,不知道的,Get到了记得顺手点个赞哈。

正文

1、接口别随便暴露

当一个项目的维护周期拉长的时候,不断有新增的需求,如果经手的人也越来越多,接口是会肉眼可见增多的。

此时,如果一个团队没有良好的规范和代码审查机制,就会导致许多不安全的接口被暴露出来。

比如下面这种接口:

/**
* 根据ID查询患者信息
*/
@GetMapping("/{id}")
public AjaxResult getById(@PathVariable("id") Long id) {
    PersonInfo personInfo = personInfoService.selectPersonInfoById(id);
    return AjaxResult.success(personInfo);
}

这种接口是我们部门以前审查出来的其中一个,类似这样的接口还有很多。

这些接口都是不同的同事在紧凑的工作任务中写的,慢慢就积累出了一堆。

还有些是为了方便,直接通过代码生成器生成的,而代码生成器是把常用的CRUD接口都给你生成出来,如果研发人员没有责任心,可能就直接不管了,想着以后哪一天也许会用上呢。

别以为这种想法的人少啊,你整个职业生涯很可能就会遇见。

这就导致了,一堆用不上又不安全的接口出现了。

服务过政务机构、企事业单位、医疗等行业的工程师应该就知道,这些单位对于安全性的要求其实挺高的,尤其是这些年,会找专门的信息安全公司做攻防演练。

最近两年,很多省市甚至会自发组织全市的信息安全攻防演练,在当前大环境下这也是符合国情的。

而攻防演练的目的之一就是找系统安全漏洞,这里面就会有一个我本章要讲的典型漏洞,接口的横向越权。

2、什么是横向越权

广义的解释就是,该越权行为允许用户获取他们正常情况下无权访问的信息或执行操作。

如果纯粹从理论上理解,是很抽象的,所以我才把这个案例捞出来,让你一次就懂。

我们再回过头看看上面我贴出来的那段很正常的代码,就是根据id获取用户信息,你一定曾经在一些项目中见过这种接口,提供给前端直接调用,比如用户详情、订单详情,只要是和详情有关的,很可能前端会需要这么一个接口。

那么,问题在这里,我们的id是不是有规则的呢?比如下面这样:

1.jpg

可以看出来,id是自增的,增量是2。其实很多中小企业现在用MySQL都喜欢这样设置自增id,有些会设置增量,有些干脆就默认。

试想一下,我如果知道了id=865的用户信息,我也知道大部分中小企业喜欢用自增id,是不是就等于知道了1-1000000的用户信息,而用户信息可能包含身份证、手机号、详细住址等非常敏感的内容。

这就是典型的横向越权之一,我明明只应该拿到id=865这个用户的信息,但是通过非正常的方式,我暴力获取了其他100万个用户信息。

一旦真的发生这样的事故,不管最终结果如何,这家公司基本上就进黑名单了,从此在行业中消失。

3、权限控制不了吗

一定会有人产生疑惑,SpringBoot接口怎么可能直接放出来,一定都是有权限控制的,没有权限是根本不可能访问到的。

我打个比方,如果是后台管理这种,他是有登录的,登录后会产生token,token中是可以包含角色权限的,那么这种是没有问题的。

但如果没有登录操作呢,比如小程序这种,你打开就直接是首页各种信息,前端调接口很可能传递的只有网关层的token,又该如何呢。

尤其是小程序雨后春笋一般涌现的那几年,我曾经打开过很多小程序,都是没什么权限校验的,就是直接点来点去。

直到近几年,这种现象才慢慢消失,很多小程序打开后,会提示你授权登录,比如微信小程序,你一定遇到过打开小程序后让你授权登录的场景,如果不授权登录,你绝对做不了很多操作,这是很多互联网企业的安全意识都加强的结果。

我所在的公司早年刚进入医疗行业就经历过这种事情,为了占坑拿下了很多项目,但缺乏安全意识和管理规范,程序员也是来来走走,你写两个我写两个,导致不少接口都存在安全隐患。

直到被攻防演练攻破,甲方下发整改通知,还要我们写事故报告、原因、解决方案等等一大堆,我们才慌了。

连夜开会讨论出一套基本的安全整改思路,然后开始加班加点做安全改造。

我印象最深的就是其中这个接口横向越权,只传递了网关层的token,而没有细化到个人的权限控制,导致被信息安全公司通过抓包等一些我不了解的技术把token拿到了,然后直接横向获取到了很多用户敏感信息。

当时这个事情闹得很厉害,考虑到只是攻防演练,同时客户方对公司还保留信任,才只要求我们限期整改,否则就直接替换了。

所以,记得以后写接口的时候别只考虑业务逻辑,安全性也是考量之一。

4、如何防范

防范的方式,我归纳了这么几点:

1、不用的接口尽量删掉,这样也避免了多余接口埋下的安全隐患;

2、团队要有安全规范,比如敏感字段加密,引入代码审查机制,缩小安全隐患出现的范围;

3、带登录的终端,除了网关层校验,要精确控制登录用户的角色及权限;

4、不带登录的终端,除了网关层校验,要根据用户的唯一信息,来做授权登录,授权不成功不允许做其他操作,这也是现在比较流行的方式。

我个人理解,第4点和第3点本质一样,因为不带登录,所以要想办法制造登录,而目前比较友好的方式还是一键授权登录,不管是根据openid、手机号等等,总之要找到一个规则,这样省去了用户手动操作登录的时间。

总之,一定要控制用户只能看到属于自己的内容,避免横向越权。

总结

如果写的不好,还望大家原谅,只是分享了曾经工作中发生过的和安全改造有关的事情。

现在的程序员其实了解和接收的知识技术是挺多的,许多人其实都知道这些。

希望不知道的人,能够因为我的文章得到一点点帮助。

最后,大家其实可以去试一试,打开微信小程序,搜索下你们所在城市的某某中心医院,看看这样的医疗小程序打开后是什么样的,是不是有授权登录,或者其他方式来控制权限,搞不好一部分人能遇到有意思的事情。


如果喜欢,请点赞关注哦↓↓↓,持续分享干货!