随着应用越来越多 ,全风每天大量的险主代码变更会带来很多潜在的安全风险,如果这些风险没有被挖掘出来带病上线,动感那我们暴露出去的知度风险就会越来越多,如何在代码变更后及时的量探感知到这些风险成为非常重要的事情,只有及时的全风感知
,才能确保风险能得到检测和确认,险主而目前我们尚没有这样的动感机制来确保代码变更产生风险时第一时间展示出来并布置更多的跟进处理措施,这样就会不断的服务器租用知度有新的风险暴露出去。 当src又又收到外部白帽子提交的量探漏洞时,复盘大会上我们该怎么说呢?全风 以上回复基本都是因为没测到、没来的及测,总结下就是两个很关键的点没有得到保障 综上,当应用更新时只有及时全面的进行安全测试才能确保应用是相对安全的
,那么及时和全面就分别对应测试时效性和测试覆盖度 先说下测试覆盖度,安全测试和业务(质量)测试(QUALITY ASSURANCE)同学的工作性质有点类似,亿华云如果有个功能点或者api没测试到根据墨菲定律这个点就很容易会出现问题 ,那么如何避免这个问题呢 ,那就是需要有平台有数据来量化测试覆盖度 ,这个平台有多少api,测试了多少
,测试了多少不同类型的case,测试覆盖度依赖于以上数据
。 如果每次研发同学发布了新的代码,安全同学如果都是一年以后来检查这些代码有没有新的风险那安全检测的意义好像就变低了 ,当然现实中是香港云服务器不可避免的人力不足,比如一个安全同学负责成百上千个应用的安全,如果没有好用的自动化工具那么安全同学其实是很难应付的过来,安全测试的时效性就很难保障,目前集团有非常棒的扫描平台来支持我们做白盒扫描/黑盒扫描,同时目前iast模式的灰盒测试也在推广中了
,这些都是非常棒的实践。源码下载 度量的目的是让我们能够清楚的知道我们的工作重点应该在哪里,不能为了度量而度量,度量或者分析后面应该跟进很多安全动作 ,比如新增了接口就需要及时的进行安全测试
,这样就能确保每个新增api及时的得到安全测试
,这样就能覆盖全部的api
,同时保证了时效性。要确保覆盖度 ,免费模板最重要的一点就是我们需要知道我们的分子 、分母分别是什么 。不同的应用对外提供服务的方式不一样,基于目前B/S 、C/S架构来讲 ,目前绝大多数风险在S端对应的后端应用上 ,目前对公网开放应用绝大多数还是通过rest-api的方式提供服务,后端服务除了api还有大量的rpc接口,目前来看webx、springboot、nodejs等框架类应用普及率越来越高 ,那么我们就拿webx为例来分享下如何做到应用风险可见,那我们思考下,一个应用在merge代码的时候可能会带来哪些安全问题,针对使用最多的java应用,我总结了两点 1 更新了pom文件,引入/消除了新的存在问题的二/三方组件 理论上只要我们分析出以上两个变更就可以非常清楚的知道一次commit到底会不会带来新的风险 ,对于一些特殊场景,比如api下线 ,不仅仅意味着风险的消亡,同样意味着我们需要去更新我们的资产库标记相应的api已下线。 要确保一个应用中的api/rpc接口全部得到测试 ,我们就需要获取到一个应用中包含的全部api/rpc接口,这是我们计算测试覆盖度的分母,而且随着应用代码的迭代这个分母是变化的,这个分母的变化就会带来风险
。 pom里更新组件带来的问题目前基于漏洞库已经基本上覆盖掉了,那我们说下第二点 api层面的变更和api调用链的变化 从上图我们举个栗子来讲 ,先从commit1和commit2来讲下,假设commit1的时候我们通过自动化 、人工确认应用是相对安全的了 ,那我们标记应用当前的状态是 safe
,当监控到应用有merge时,也就是应用处于commit2状态时我们通过自动化分析发现api还是3个,但是api2的调用链上某个方法发生了变化,这时候我们就需要标注出当前应用因为代码更新新增的风险是 api2的调用链上某个方法发生变更了,这时候就需要我们去确认是否有新增风险。 再比如commit2到commit3
,新增了一个api4
,这时候 新增的这个api4 就是需要我们去关注的风险 。 按照上面的逻辑
,我们应该可以把新增的风险梳理出来,主要是防止新增风险慢慢变成存量风险
,不积硅步无以至千里 ,哎,好像不大应景。
。。 就像前面说的一个应用对外提供服务基本就两种方式,一个是rest-api
,一个是rpc接口,也就是对一个应用而言除去运行环境下,暴露的攻击面就是各种接口了, 这就是一个应用全部的分母 ,也就是我们保护的对象
。 要想保证分子是更加接近分母就需要思考以下问题 , 这个应用有多少api ?(资产库)这些api测试了吗 ? 2.1 谁测试的? 2.2 什么时候测试的? 2.3 测试时候的代码和现在的代码一样吗?也就是现在的api还是当时的api吗
?不会更新了吧
?不会回滚了吧 ? 2.4 测试记录还在吗?(怎么证明你测了
! ! !) 当前最实际的问题是线上运行的成千上万的应用中包含的漏洞该怎么挖掘出来,同时怎么防止新增风险变成存量风险。这两个问题中更重要的应该是怎么防止新增风险变成存量风险,否则我们就会陷入一直在处理存量风险的困境。那么让新增风险可见就变成了一个非常紧急且重要的事情。要实现风险可见需要几个关键点 。 风险可见的关键点: 而要实现第二点就需要把每个api对应的调用链和调用链上的各个方法统一存储进来方便进行比对 。 此图为在猿辅导打工时团队产出的脑图(手动感谢andr01la 、l4yn3liu、T00ls01) 基于上图拿内部某个应用进行实践,通过实践我们可以输出代码变更时是否有新的api产生,是否有api对应的调用链的变化 使用AST梳理api可以根据类或者方法注解进行查找,最常见的注解为以下几类 复制a. @Controller b. @RestController c. @ResourceMapping 比如针对以下代码通过分析注解也可以获取到类似swagger的数据输出 @RestController @Slf4j @Autowired 从某个api开始分析 复制@Verify throws /contract/buy/queryInfoByEmail.json对应的入口方法是queryInfoByEmail,从该方法做为开始我们通过codeQL获取其调用链上的各个方法 以上我们通过批量、递归操作就可以获取到一个api对应的入口方法开始其中调用链上的各个方法和在代码中的索引值 ,知道了索引值也就可以从源码中获取到每个方法的代码块和调用位置,就可以获取到类似以下的信息 如此就可以获取到某个应用某个commitid下api对应的调用链信息和每个方法的具体代码了,当应用被更新时
,重新执行以上流程就可以获取到在新的commitid下api信息以及调用链信息
,对信息进行比对就可以获取到差异,而风险就存在于变化之中
。 以上我们可以获取到api以及api调用上的变化,那么这些变化就是需要确认的风险点,通过产品或者平台将这些信息展示出来我们就可以很直观的看到风险点,下一步就是确认这些风险是否是需要进一步处理的,最原始的方法就是人工确认,最起码这就有了一个可以做动作的入口
。同时如果通过自动化手段可以把api
、api调用链变化信息
、调用链中每个方法的源码、api测试样例都能在一套平台里展示出来,那都将极大的提升审查漏洞、复核漏洞的效率 。 一部分通过AST解析获取代码中的api,另一部分来自于流量清洗获取。 这两种方式各有优劣,ast准确率高但是缺少请求样例,流量中解析需要做归一化处理,如果处理不好一个应用下就变成了有十几万API,优势就是有请求样例(request、response),如果ast和流量解析出来的请求能统一起来 ,那么我们就可以获取到指定应用下有多少api、api入口类和方法 、请求样例、对应的响应样例
,这样一个应用下基础信息就有了。后续每个api会透出什么信息、是哪类敏感信息就都可以做了。 不管是所谓的大厂还是小厂 ,真正接触过后才知道很多应用其实是根本没有做过安全测试的
,有些是没有流量触发不了扫描,有些是post接口担心影响业务不敢扫
,假如有了前面的api列表信息,并且黑盒能够标注哪些做过检测了,检测的漏洞类型是什么都记录下来,那么我们就可以很清晰的知道咱们应用哪些漏洞类型还没有做检测,没有做的检测就需要我们黑白盒
、安全运营工程师一起努力来打造 、提升检测能力;另一方面外部提交漏洞时也可以快速的复盘知道这个api我们内部到底有没有测试到这个api 、何时、何人测试的。 前面同样铺垫过了,所有的变化都是需要能被感知到的,并且需要有能力检测到哪些变更会带来风险,带来的风险需要谁去判断是否真正存在漏洞 ,谁来卡点?是统一在一个平台比如soc处理,还是需要安全工程师来回切换,比如接口是mtop发布然后就需要去mtop看接口信息 、看入参、出参? 以上是最近在安全运营工作中在遇到一些迷惑之处的思考
,大佬们有其他意见和建议也可以在下方留言或者wx(m0l1ce)0x1 背景
0x2 及时全面
0x201 测试覆盖度
0x202 测试时效性
0x3 风险度量
0x301 覆盖率中的变化的分母

0x302 谁来保证分子
0x4 新增风险分析实践

0x401 基于ast分析api/rpc接口
0x40101 rest-api
0x402 调用链关系获取
复制条条大路通罗马,获取调用链的方式有很多种,现在我用codeql简单的拿某个api演示下获取调用链以后可以做哪些事情1. 


0x403 产品化
0x5 需要的能力
0x501 API发现能力
0x502 检测能力量化
0x503 接口变更感知能力
0x6 总结