书评-《企业级自动化代码安全扫描实战》

    近日百度安全应急响应中心发布了《企业级自动化代码安全扫描实战》,读者可以管中窥豹来实例了解软件安全中白盒扫描领域在互联网公司的落地情况、理解该业界的技术方向趋势和进展、查漏补缺发现企业内部建设不足、对标评估自研安全能力,立足自有工具现状制定改进计划。 

概述

    软件行业在全球不断出现的重大安全事件敲打下,在设计阶段、协议实现、编译检查、框架集成、加密方案方面已经有了众多优秀改进方案。各项软件工具包括p3c、npm audit fix、spotbugs可以让研发人员更快速地实现并交付健壮的代码。商业安全工具和开源社区共建使用sonarcube、findsecbugs、bandit、golint、rips协助安全人员相对准确地找到安全缺陷。同时伴随着企业专职安全团队中的S-SDLC人员的逐步完善和资源的增加投入,专业化服务能力提升使得组织可以尝试发力于流程建设和深耕运营。安全审计人员的主要任务逐步从人工审计转为将自动化、智能化、标准化、数据化融入技术固化在产品之中。但是业界每个公司所能看到的“微软安全开发生命周期”时间已经深度耦合于组织内部的开发模式和标准流程,或者其自称为敏捷sdlc。对于读者动手实现来说难以快速移植,值得庆幸的是源代码审计这个环节可以快速适配企业在各个阶段的安全建设,作为价值交付固定持续产出。

    源代码安全建设普遍做法一般分为五个发展阶段:人工review(seay、ctrl+f)、ide辅助、词法分析阶段、使用支持各种语言的多项开源源代码安全检查工具、重视安全的企业花钱采购商业源代码安全工具。在具备二次开发和调用api接口能力的情况下增改适配规则,开发导出、查看、验证分析报告功能,打通开发流程,数据流转同企业内部的jira、禅道、漏洞平台、src闭环结合起来。实现持续运营和数据推动改进动作的思路和效果。

大型企业一般面临三个问题

    1、不同部门用的技术栈不同,前后端技术也不一致。推广阶段要对不同开发风格适配和维护各项开源工具的编译命令规则和报告。当然这并不现实,所以一般做法是使用商业安全工具为基础引擎,进行一套自动化的代码扫描接入、改进和推广。在基本实现一定的覆盖率的情况下,实现对不同部门、不同业务线制定不同扫描规则和“门槛指标”,耐心收敛漏洞。

    2、存量代码太多。由于基于svn、gitlab、stash的代码提交方式各有各的痛点,在没有搭建存储和代码检索平台的情况下,人工在应急响应时无法快速准确判断是否受影响,在事后难以增加管控增量代码的感知和控制手段。大量新增代码不同分支、对应不同线上线下域名、环境、发布平台。任何一件事的量级增加都是对工程化的巨大考验。

    3、安全人力资源投入。代码审计的需要懂开发和安全的员工,虽然我们都知道安全专家介入到需求阶段效果最好、成本最低,但是依赖人工根据终将处于疲劳的应接不暇阶段(所以阿里巴巴做了大量的工具和系统)。而人参与的工作终究会有漏报,在事后回顾aar时也没有更好的改进手段,只能不停做专项。安排了周期性专项或者新增一个checklist动作,本季度漏洞数量会上升,但这又没有用呢?解决方案如同黑盒扫描器的治理思路一样--源代码的高阶实现有且只有依赖于自动化手段。

    4、职责区分。为什么安全部门要做源代码检测?企业内部配置的专职QA、PMO或者RD自测时通过测试用例来保证需求清单的功能特性得到实现,这种前提下将漏掉一些安全方面的考虑,缺失对软件功能安全和安全功能缺陷的检测和修复,同时增加成本。由安全专家制定出来的检测规则可以保证具备更好的准确性,更新可以及时跟进和更高的可信度,也有利于后续的数据度量维护。

什么是漏洞?

    源代码检测的安全和质量部门的检测有何不同请看下图:

    源码扫描作为安全运营的一个阶段将安全流程在需求、架构、设计、编码、测试、验证阶段进行度量和维护。

自动化代码挖掘技术

基于污点传播分析的自动化挖掘技术

    回顾下有经验的安全测试人员在实施人工代码审计时的流程规范,再通过观察来仔细思考软件静态分析该怎么做,才知道如何在竞争当中树立竞争优势。

图片来自于《CTF 从入门到放弃》

    1、首先灵活指定或假定输入源是否可信、能否被污染(taint)。这类似于参考威胁建模的信任边界和数据流概念。一般认为来自于网络请求header、cookies、参数、socket网络通讯、数据库存储的数据是不可信的。当然你可以设计指定来自于环境变量、配置文件、反序列类为不可信数据。

    2、据此可以指定需要关注的程序内部函数,继而分析查看上述的污染源是否经过安全处理(即净化)。这里对外部引用的安全sdk里的安全函数如阿里的midway-security、owasp的esapi检测和识别会是工作中误报较多的场景。有时候扫描工具不支持识别该净化函数,有时候是研发人员对漏洞理解不足导致净化函数使用不准确。安全团队在实施时也会考虑提供净化函数提供给业务接入,目的是简单高效解决问题,最后在修复阶段需要复查--是否是完善的修复方案,能否被绕过。最后统计净化函数的覆盖率。

    3、最后是实施阶段性审计,执行测试用例,希冀被危险函数触发执行。所以这是一种基于跟踪数据在程序里的传递流转进行分析的技术。

    了解到上面的普遍性技术就清楚整个检测技术的要点。文章里介绍了php的检测和实现思路,实现方式可以参考看看cobra的开源代码实现。其实对于java各自纷繁的框架和反射机制、nodejs灵活的写法,非商业工具还是会遇到各项困难,如状态爆炸。词法分析、数据控制流分析、抽象语法树分析、规则检测技术相辅相成,不得不承认有时候直接用正则匹配文件未必不是一个捷径。反正都是基于“规则”进行检测的只要保证低误报、漏报率即可。

三、企业级研发与部署方案

企业级实际场景和挑战

    商业扫描工具基于license部署的情况导致软件分发一般不直接安装于rd的个人机,基于ide的场景也需要在PC安装扫描软件客户端。找八哥、checkmars基于云、coverity、foritify、cobot重量级。以至于华为公司需要安排专职人员负责持续集成,专人申请机器搭建环境进行代码编译,扫描生成中间件后再上传到商业安全工具平台,排队等待导出下载结果。而这种方式将难懂的安全报告直接交给业务线并不能统计数据和保证rd完全理解结果,还得建立社区去答疑。假使集团最终出现安全漏洞还是被认为没有将安全能力赋能于业务。哪怕兢兢业业提供了详细可读的报告,报告的可读性、整改实际情况都是一项挑战和dirty work。

    安全人员顺其自然想到做一个平台来支持推广、自动化功能和支持第三方接入。实现系统工程化的集中管控、任务序列处理、工单联动,最后出具图表通知和提供外部api进行能力输出、计费。

    软件上线前必须通过安全扫描这件事情隐含的前提是需要明确“卡位”点。哪些是新业务?对于迭代任务是否需要接入将安全作为一个环节融入在软件研发的持续集成活动中?存量业务怎么做?

    安全红线在于指标的制定,只有在确定单一条扫描规则的准确度高、扫描速度快的情况下,才可以对不安全的组件、严重、高危漏洞进行阻断发布。

整体架构

    评估源码扫描系统的指标一是架构的部署和设计、二是性能优良的规则的多寡。架构方面大都类通过扫描接口获取到任务上线列表、复查请求、手动创建任务、创建策略,依据优先级指定扫描规则下发至持续集成集群,由slave调配job进行编译,异步检测是否成功、推送扫描结果。CI带动扫描引擎将商业安全工具和自研的规则程序跑起来。引擎管理层收集结果入库或本地生成报告。在源代码管理层面配置各项账户拉取代码。由于部分语言代码扫描时需要编译,需要将代码保存在机器上。实际中的痛点会是数据量大导致存在同企业发布平台拉取的代码重复的情况。这里建议将代码做索引以便搜索和查询。比对汽车之家、京东的源码平台建设资料可以看到百度在任务管理、增量存储方面做得更为先进,值得学习。

SDL中实践

    由于将安全扫描作为发布的必须环节实际上将业务的编译阶段重复执行了一次,所以必须保证扫描结果较快,基于解释性语言的话扫描会慢得多。这里的增量策略的必要性在于--某些扫描引擎不支持增量扫描,所以动手开发匹配识别增量文件,确定同源向量,扩展拉取引用的函数和代码文件。补全语义分析或者控制流分析流程。好处是这里可以清晰地获取到数据的调用流转过程,程序自动对此生成调用关系链图,来帮助业务在修复时快速了解漏洞的前因后果,减少人工答疑时间,保障SLA。

    无变更文件不进行扫描的特殊场景需要考虑到:账户密码文件等不经常变更,需要对此进行甄别识别来整改配置文件明文密码的情况。

    企业内部凌晨反而经常是资源紧张的时候,可以在周末单独跑序列对扫描失败的任务、漏洞已经修复待检验的代码进行复扫,实现自动关闭工单。

平台检测效果

    从效果上看,增量的任务可以保证完全接入,对于存量只得人工接入,存量的代码总是好几年前的,经常是找不到漏洞责任人,这时候索性就不提交或者记为遗留任务。漏洞规则方面应当支持src收集到的公司典型漏洞和owasp通用漏洞。

最终切记:源码分析的不足是不能发现业务相关的漏洞如水平垂直越权、信息泄露。

java漏洞检测

    查询pom.xml\build.gradle配置文件读取第三方组件分为未编译和已编译两种情况,使用dependency-tree得到的的结果不准确,对于多module的情况需要识别version的配置。最后维护一份同cve的对应关系就可以做到组件管理。开源组件可以考虑使用dependency check,在集成扫描时增加一条命令即可,portal可采用dependency track。

展望和感想:

    企业使用sonarcube来联动jira搭建如何

    sonar的特点是开源免费、代码规范类规则可以简单自定义、dashboard展示和统计功能优秀、扫描速度快,但这类工具只能称为static code analysis,可以用在起步阶段,维护起来成本较高、需要专人来测试和开发。安全团队关注security code analysis,需要摒除测试、质量、编码规范的结果。sonar基于模式匹配规则的整体误报率介于80%-90%。这么算起来,商业工具的性价比更高。如果你已经使用了请不用着急,各种静态代码分析结果只要遵循标准,都可以互相兼容转换。如果漏洞整改要继续贴近业务,通过工单1v1推动就不现实了,通过sonar都hook机制,在code review阶段介入对于小团队获取是个好都切入点,类似于gerrit。

未来重点技术

    第三方代码供应链安全研究,代码不仅仅是写出来的,各种导包、软件源将是关注的重点。阿里和腾讯近年来逐步关注。

图片来自于seczone

    AI|机器学习,目前已知foritify\cobot的产品“宣称”已经使用了相关技术,但是分析建设模型的前提训练方法对大量的输入样本数据的投喂分析,目前仍需收集数据,未来虽不能全交给AI,但是可以考虑将AI服务于辅助传统分析工具,当前还远远未达到智能化、科学化。无监督机器学习的落地,可以由大量的扫描结果、代码特征、训练资料中学到或建立一个模式,实现“代码未写、漏洞已出”。

静态代码分析和人工审查的区别

    当前技术层次上来看,源码市场上无非也就是那三四种,Foritify,AppScan for code, Checkmarx,coverity,google的叫做gerrit\ errorprone\ shipshape,大公司可能有自己的工具,但是没商业化或者没放出来外界没法接触到。实际代码审计维护人员中总是在误报、漏报、正确配置三件事情上忙活,走开发规则、确保准确的配置、完善检测模型这三板斧。当然本身大量的误报还是需要人工来验证,高级漏洞依靠经验发现仍然是主流(Semmle QL将编译后的结果保存,提供类SQL的查询语言,支持深度语义代码检索,发现不少cve)。人、工具、代码之间需要结合公司具体情况做权衡和平衡。SDL团队初建,没足够的人手,以工具优先。

安全缺陷不是漏洞

    搭建好白盒系统后的窘境是扫描发现的问题并不总是漏洞,仅仅是"不安全编码实现”。需要坚持安全理论指明安全防御需要进行纵深防御,而不仅仅是外部进行防护。对业务说明:首先最外层肯定是要处理这些数据验证问题,其次各层系统之间的信任之间需要有相关的安全措施。浅显的例子是SQL注入语句虽直接由数据库实现,但是最终由于各种原因,数据库这边对SQL注入无法处理,仍然坚持自己只作为数据库实现的功能,只能在软件编码实现阶段来完成加固。安全的问题很大程度上是信任的问题,中间件说它信任上层应用的数据。实际上要去研究下上层应用是否都是值得信任的。如果是复杂的系统,甚至有提供给第三方的,很难保证所有的外界输入都已经被妥善处理 。

漏洞修复要求

    验收需要建立高标准,认为内外网漏洞没有区别,没有waf、hids、rasp、firewalls。这个情况很像消防制度、烟雾报警器、消防员灭火三者的关系。对于不同的应用来说需要执行的指令是不同的,比如一个数据库管理的软件,就是要传送sql指令的,这时候就没法过滤或者参数化。所以有时候提供修复方案的理论和实际理想情况差别很大,只能说是结合具体场景具体分析,终归让rd把代码修复了。特殊场景如rpc调用,一般也就是最多在前面2、3层应用都要求对输入进行处理,再后面的系统,也是没法再要求了。

    如果外层仅仅是个别自己可信任的应用提供数据给中间件,那么就实际效果来看,中间件不愿意处理也说得过去。但是如果外层太多就很难控制住。而且就安全来说,能集中化处理的就尽量集中化处理。举个例子:某个系统对外提供一个接口,那么如果外层就1、2个系统用,那么实际效果来看,那1、2个系统中都对数据进行了正确验证,接口这边即使不验证,也是安全的。但是如果外层有几十个,甚至更多应用来用,或者说以后调用的数量扩展了,那么接口这边如果不做集中化的验证,那就很复杂了(《阿里巴巴java开发手册》要求对接口全部做验证》)。面对源码扫描结果,需要在灵活,易用和安全侧重点取个平衡。

SDL推行

    如果要是没有上面高层的强力支持,很难推下去的,阻力太大。开发基本不关心安全不安全,关心的是自己的任务能不能即使完成,pm也是更关注项目进度。而安全通常会给项目带来额外的资源消耗,无论是人力还是时间。而互联网公司有很鲜明的特点: 1. 开发周期快 2. 产品开发多 3. SDL人员少,想要执行完整的SDL流程,恐怕是行不通的,SDL基本上可以说是100%会被整个开发团队反感,我们工作接触多的code review和开发的code review还不是一回事,门槛更高,而且由于工具的太过于昂贵,一般公司没有设立相应的职位或者职位继续不下去。

流程制度方面

    可以看看http://www.owasp.org.cn/owasp-project/download/owasp-samm samm将源码审计分步骤推行,也挺适合互联网公司的,是个非大型专业软件公司版的微软SDL,其实流程和要求和SDL已经差别不大了,还是1. 人员要求高 2. 成本大,和SDLC一样的缺点,它好在于有三个等级,可以慢慢一步步提高。目前其实国内SDL很难做“到位”,依托于代码审计,在安全检测、漏洞审计、修复、闭环逐步做好。如果面临项目周期短,发布快,项目又多,安全人员少,只能尽量走自动化路线,但是像漏洞和代码分析,架构设计安全审计方面自动化目前还无法办到。SDL除非是公司有足够高的层次支持,使之成为像软件开发流程那样的基本工作流程才行。这里分为两种情况,将安全作为产品的基本需求特性,卖软件的厂商,另外一种是开发的产品自用,两者对于安全性的初心是不一样的。

搭建系统需要的团队

    实施人员的角色--"软件安全人员"需要了解编码开发和系统架构。搭班子时可以从开发人员入手,然后灌输他们相关安全知识。如果从网络安全人员入手, 并试图向他们讲解有关软件、编译器、SDLC、bug跟踪以及软件领域的所有其他知识,实操效果一般。另外需要掌握的技能是持续集成方面的构建知识。优秀的代码审查人员常常并不懂得如何进行系统设计层面的分析。此外团队需要跨部门沟通、培训、指导,需要有人具备良好的沟通能力、教学能力和实践知识,负责对外宣传和搭建群去反馈、答疑,建立分散式的虚拟组织,培养对软件安全有兴趣的测试、开发人员。共建形成合力去推广源代码扫描。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值