郭振新:软件安全研发建设之路

2023-07-06 14:26 郭振新

作者简介:郭振新,OWASP中国吉林区域负责人,某外企安全部门负责人,资深研发工程师。拥有11年软件安全和软件研发经验,软件公司安全研发流程和安全团队从0到1的建设经验。


关于软件安全研发建设,每个公司的实际情况不同,所拥有的资源以及面临的业务场景也不一样,所以解决方案也会有一定的差异。本文分享一些软件安全研发的经验,希望可以给各位读者带来一些帮助和启发。


一、软件安全研发流程实践

软件安全研发流程的设计,首先需要定义几个关键角色,分别是:安全团队、产品安全负责人和常规测试团队的安全测试人员。


安全团队,以我们团队为例,除了合规相关的工作较少(主要总部在负责),其他与软件安全相关的工作都要做,包括渗透测试、安全设计流程、安全技术培训、安全技术积累、安全运营、安全事件调查等等。


产品安全负责人,主要的责任是把控产品迭代过程中和安全相关的工作,保证执行到位。然后要确保安全部门的培训、任务、信息能有效传达到产品团队。


常规测试团队的安全测试人员,由于公司产品较多,安全部门资源又有限,所以由常规测试人员来学习渗透测试和漏洞扫描,可以缓解很大一部分工作压力。经过实践,测试团队可以胜任简单的渗透测试的工作。我们的做法是,首先由安全团队来培训测试团队基础的测试步骤,比如如何测试权限、如何测试前后台的参数验证等,然后写成测试案例,交给测试团队执行基本的渗透测试。这样可以大大节省安全团队的资源,也可以对提高应用安全起到很大的作用。


产品迭代中的安全工作


在产品迭代过程中,要做的任务包括安全设计流程、静态代码分析、软件组成分析、容器镜像扫描、主机漏洞扫描及安全加固、动态应用安全测试、常规测试人员测试基本安全测试用例、上线等。


众所周知,从研发、测试、发布到运营的不同阶段,漏洞修复成本是成倍增长的,所以现在软件安全行业特别推崇“安全左移”,以期能够尽早发现问题,并降低修复成本。然而很多企业的“安全左移”就是“IDE+静态代码分析插件”,但其实两者并不等同,虽然“IDE+静态代码分析插件”确实能发现一些问题,但也仅局限于静态代码分析能发现的问题,而像业务逻辑问题或权限问题是无法被发现的,所以要做到“安全左移”,需要从设计阶段就考虑安全。


安全设计流程

当然理论上修改任何代码都可能带来安全问题,然而评估任何代码改动是否会引起安全问题显然是不切实际的,所以我们制定了这个安全设计流程。


如上图所示,是我们设计的一套安全设计流程。迭代刚开始,产品安全负责人需要检查本次迭代和安全相关的一些功能,然后把这些功能挑出来,通过邮件发给安全部门,审核该功能是否和安全相关,是否需要安全设计文档。关于安全设计文档,有一点需要说明,并不是所有的功能都需要安全设计文档,比如需要在页面上加一个富文本编辑器,很显然这个功能不需要写文档去说明开发的用处,只需要告知这个功能,由安全部门确认之后,再邮件告知产品安全负责人哪些功能与安全相关并且是否需要安全文档来解释该功能的作用。


安全负责人收到邮件之后,针对每个功能会创建安全审核Jira,然后在开发之前确认是否需要安全设计文档,如果需要则进行文档审核以及信息提供,然后进行开发,如果不需要则直接开发即可。开发完成之后,开始渗透测试。在渗透测试这块也有一个分流,比如说开发修改了权限模型,渗透测试的工作量会非常大,因为每个API或每个页面可能都需要测试,这时就需要常规测试人员的帮助。


做这套流程主要有两个目的:第一,优先挑选重要的和安全相关的功能和逻辑,这样就可以做安全设计流程,让开发人员提供文档,尤其在开发人员写代码之前注意可能存在的问题。第二,即使不写安全设计文档,也可以把较大可能产生漏洞的功能列出来,知道哪些产品添加了哪些功能,这些功能是否更容易出现问题,是否需要渗透测试。


开始推动这套流程时,我们发现产品安全负责人的安全意识不足,挑不出哪些功能与安全相关。所以最初的执行是由安全部门去挑重点的产品和功能,执行了两三个迭代之后再给产品安全负责人进行培训,告知哪些功能与安全相关。结合之前的数据,产品安全负责人就可以参考这些数据在之后的工作中去挑选负责的产品是否有与安全相关的功能。经过不断的积累,产品安全负责人的安全意识逐步提升上来,就可以独立负责相关的工作。


二、软件安全研发工具

1、威胁建模


Microsoft Threat Modeling Tool是一款免费建模工具,可以针对当前的架构图评估可能面临的安全问题,以及对应的设计建议和缓解措施,同时该工具可以很好的降低威胁建模的门槛。


前面说的安全设计流程的安全设计文档,只要开发人员能把整个业务逻辑体现出来即可,说明其中可能存在的问题以及对应的预防方法,但开发人员有时不一定能完全在文档中体现,我们在审核文档时也会跟开发沟通,当前业务逻辑场景下可能发生的问题,然后跟他一起把这些问题都加到文档里,这样让开发在实现该功能之前可以了解可能会存在的问题。


2、静态代码分析(SAST)


我们使用的是SonarQube开源的静态代码分析工具,可以分析漏洞、代码质量、潜在的Bug以及代码重复率等。


使用该工具的方式是将它集成到GitLab的CI/CD流程中,每天扫描一次。扫描完后,如果有问题就会给对应的开发人员发邮件,通知他有新的问题需要修改。


3、软件组成分析(SCA)


在当前网络环境下,供应链攻击是我们需要面对的重大挑战,比如像Log4j这种级别的漏洞肯定是越早发现越好,而且使用不安全的组件,一直都是OWASP Top 10中的一个重要威胁。


我们使用的工具是OWASP的开源工具OWASP Dependency-Check,可以用于识别依赖项,并且检查依赖项中是否存在公开披露的漏洞。执行原理就是把几个漏洞数据库下载下来,和代码组件进行匹配。


使用方法是把它集成到SonarQube中,同时在SonarQube的GitLab的CI/CD流程中添加Dependency-Check,每天扫描一次。有问题会通过邮件形式通知开发人员修改,结果可以显示在SonarQube中。


4、容器镜像扫描


我们使用的是Trivy,可以扫描的内容很多,包括扫描镜像中操作系统软件包、应用程序依赖项、软件的许可证以及配置文件中的安全问题。该工具使用很方便,而且结果精确。


使用方式是把它集成到GitLab的CI/CD流程中,每次打包都会扫描。另外也做了一些额外的集成,有问题可以自动的创建Jira跟踪,开发人员看到Jira就会去解决问题。


5、动态应用安全测试(DAST)


DAST基本上是每个做安全的企业首先要做的事,我们使用过三款DAST工具,分别是Acunetix(AWVS)、Burp Suite Professional和OWASP ZAP,经过对比其结果也是大同小异。


针对DAST比较重要的两点是,第一是扫描时要保持登录状态,因为现在做的应用程序基本都需要登录,登录之后才能使用里面的功能,所以没有一个登录脚本,是不可能扫描到登录后的页面的。第二点是对于整个网站是否扫描足够全面,也就是爬网逻辑。关于这两点,这三款工具都没有很完美,因为每个产品用的前端技术都不太一样,所以对于这种网站的扫描总是差强人意。


我们的做法是让测试人员把要测试的功能先清点一遍,把收集来的请求导入到工具中再进行扫描。但局限于上面描述的两点,没有办法将DAST集成到CI/CD流程中,所以我们是让测试人员手动来扫描。


6、服务器漏洞扫描和安全加固


我们并不是所有的产品或组件都使用了容器化,有一些可能还在常规的服务器上。每一次迭代都会执行漏洞扫描和安全加固,使用的工具是Nessus Pro,该工具可以花钱买也可以去官网下载免费版的Nessus Essentials。


7、漏洞应急响应中心(SRC)


我们是使用Bugcrowd建立应急响应中心,这对安全部门来说也是一种工作的验收,可以验证工作的开展情况。起初我们在上线Bugcrowd时定的目标是让渗透测试人员发现不了安全漏洞去努力的,但后来发现确实做不到。


我们使用Bugcrowd一段时间,发现的问题都是一些老功能或老产品的问题,而且没有发现严重的问题。如果是经过安全设计流程的新功能,基本不会有什么问题。所以从结果来看,安全设计流程这套方法对于软件安全有很大帮助。


三、安全团队建设

组建安全团队有两个渠道,分别是招聘和内部培养。当然,招聘是最快最直接补充有生力量的一个方法,但是我们公司是在二三线城市,很难招到合适的人才,所以我们是两条路并行,侧重于内部培养。


因为我们是一家软件研发公司,研发人员比较多,占公司人员的一半左右,而且因为是在二三线城市,人员留存率很高,所以培养研发人员转行到安全的操作性更强,而且培养出来的人也完全符合自身的要求。我们的做法是挑出来一些对安全感兴趣的人,让他们每天抽出来一两个小时学习渗透测试和安全相关的技术,如果合适再慢慢转到半全职或者是全职做安全。


研发背景的重要性


一个没有研发背景的人,很难跟开发去讨论安全设计流程中需要注意的问题,很难全面考虑业务逻辑中的安全问题。我们团队有一位在国内某些src里做的不错的选手,他的渗透能力很强,在内网或攻击相关的技术都很擅长,比内部培养出来的研发人员强很多。但如果去做安全左移或安全设计流程的工作,还是做了四五年研发转安全的同事更好,而且面对越复杂的需求,研发经验不足带来的弊端显现的就会越大,毕竟术业有专攻。


研发转安全还有一个好处,就是在做Web渗透的同时也可以直接做代码审计。当然渗透测试人员也可以,只是效率没那么高。其实我们内部也做了一些讨论,如果看20行代码,有没有研发背景都无所谓,只要能看懂代码就行。但是如果面对大量的代码,比如一个20万行代码的产品,这时有研发背景的人做代码审计会比没有研发背景的人好很多。


在安全团队中,如果同时有渗透测试做的很好的人和有研发背景的人会更好。像前面提到的渗透能力很强的同事,在资源充足的情况下,可以让他从事一些攻击相关的研究性工作,让擅长的人做擅长的事。当然,如果想做好安全左移,保证软件安全,那么安全团队一定需要有研发背景的人。


学习建议


不管是针对个人还是公司人才培养,如果想学习应用安全技术,有几个比较好的资源。


第一,是Burp Suite Web Security Academy,可以免费注册账号使用,上面会提供Web安全的技术文档和对应的Labs,对于学Web相关的技术非常有帮助。


第二,推荐两个证书,OSCP和OSWE。OSCP,在学习过程中可以全面了解网络攻击/渗透,可以补充很多Web安全之外的技术。OSWE,针对Web安全工作的锲合度非常高,在考证过程中80%左右的内容都可以在以后的工作中用到。


软件安全研发人才培养


从我们内部的实际经验来看,在研发人员中培养安全人才的成功率大概是15:1,比如我们每次做内部安全培训,报名30人左右,留到最后的大概也就2个人左右。


培训方式,首先进行渗透测试培训,然后做Labs,再慢慢从自己负责的产品挖掘漏洞。因为本身是研发出身,对于自己负责的产品也很了解,有些就是自己写的代码,所以很容易就可以找到问题,甚至有时可以找到一些隐藏很深的问题。


安全研发人才培养成功的几点决定性因素,首先是工作饱和度,如果一个人他有时间就会愿意多学一点,但如果本身的工作每天都会加班到很晚,他就不会有时间去学习安全相关的技术,这是很重要的一个因素。其次是兴趣,兴趣是最好的老师,包括我也是因为兴趣才走上这条道路。第三是上进心,学习一项新技术肯定需要有自驱力,往往坚持到最后的可能就是上进心比较强的。最后是天赋,天赋可能说起来有点虚,但是做安全尤其是做渗透测试确实需要一些天赋,有些研发做的比较好的人在学安全时也很努力,但就是感觉不开窍,所以天赋也很重要。


当然,经过培训之后,这些人不一定会留在安全团队,但是他回到自己的团队负责某一个产品的安全,对整个公司的安全也会起到非常大的作用。