一、前言
一般安全都属于运维部下面,和上家公司的运维总监聊过几次一些日常安全工作能不能融入到DevOps中,没多久因为各种原因离职。18年入职5月一家第三方支付公司,前半年在各种检查中度过,监管形势严峻加上大领导对安全的重视(主要还是监管),所有部门19年的目标都和安全挂钩。由于支付公司需要面对各种监管机构的检查,部分安全做的比较完善,经过近一年对公司的熟悉发现应用安全方面比较薄弱。这部分业内比较好的解决方案就是SDL,和各厂商交流过之后决定自己照葫芦画瓢在公司一点一点推广。
上图为标准版的SDL,由于运维采用DevOps体系,测试也使用自动化进行功能测试,版本迭代周期比较快,安全人手不足加上对SDL的威胁建模等方法也一头雾水、如果把安全在加入整个流程会严重影响交付时间。在这种情况调研了一些业内的一些做法,决定把SDL精简化 。精简版SDL如下:
二、精简版SDL落地实践
安全培训
SDL核心之一就是安全培训,所以在安全培训上我们做了安全编码、安全意识、安全知识库、安全SDK
安全编码:
我们在网上找了一些java安全编码规范、产品安全设计及开发安全规范结合公司实际业务出了一版。
因为各种监管机构对培训都有要求,借此推了一下安全培训,定期对开发和新员工入职的培训。
安全意识:
公司有企业微信公众号,大部分员工都关注了,在公众号推广了一波。
宣传完之后答题,答题满分送小礼品
因为人手不足,而功能测试和安全测试本质上有很多相通的地方,测试部门也比较配合,针对测试人员做了一些安全测试相关的培训,但是效果并不是太理想。
安全知识库:
在漏洞修复过程中,开发很多不太了解漏洞原理、修复方案,所以我们建立了安全知识库,开发先到安全知识库查相关解决方法。找不到的再和安全人员沟通,安全人员对知识库不断更新,形成一个闭环。
安全SDK
由于公司有架构部门,开发框架基本是架构部门提供。我们将一些常见的漏洞和架构部门沟通之后,让架构将一些漏洞修复方式用SDK实现,开发只需要导入JAR包,在配置文件中配置即可。其中也挺多坑的,需要慢慢优化。
三、 安全需求设计
公司有项目立项系统,所有的项目立项都需要通过系统来进行立项,安全为必选项,评审会安全也必须要参与
这个时候基本上项目经理会找安全人员进行沟通,copy了一份VIP的产品安全设计规范,根据需求文档和项目经理确定安全需求。
确认好安全需求之后将按需求加入到需求文档,并确认安全测试时间,此流程只针对新项目,已经上线的项目的需求并未按照此流程,后续在安全测试时候会讲到这部分的项目是怎么做的。
四、开发、安全测试
安全测试主要分为代码审计,漏洞扫描,手工安全测试。由此衍生出来的安全产品分为3类。DAST:动态应用程序安全测试 (wvs,appscan)、SAST:静态应用程序安全测试 (fortify,rips)、IAST:交互式应用程序安全测试 (seeker,雳鉴),这三种产品的详细介绍可以参考https://www.aqniu.com/learn/46910.html,下图为三种产品的测试结果对比。
这几类产品实现了自动化可以继承到DevOps中。接下来我们将这些工具融入到开发测试阶段。
IAST的实现模式较多,常见的有代理模式、VPN、流量镜像、插桩模式,本文介绍最具代表性的2种模式,代理模式和插桩模式。一些调研过的产品如下图,具体测试结果就不公布了。
开发阶段
在对几类产品调研的时候发现IAST的插桩模式可以直接放到开发环境,开发环境和测试环境的代码区别主要还是在于application.yml配置文件,所以可以提前将该模式放到开发阶段。
开发写完代码提交到gitlab部署到开发环境启动应用的时候,开发需要验证一下功能是否可用,这个时候就可以检测出是否存在漏洞。
公司在测试环境使用rancher,把IAST的jar包放入到项目的gitlab,在部署的时候把代码拉到本地,通过修改Dockerfile文件把jar包添加到容器。
ADD shell/xxx.jar /home/app/xx/lib
由于公司项目基本统一使用spring-boot,所有的项目都通过一个start.sh脚本来启动应用,start.sh和Dockerfile一样需要添加到项目的gitlab,同时修改start.sh脚本文件即可。
-javaagent:$APP_HOME/lib/xx.jar -jar $APP_HOME/app/*.jar --spring.profiles.active=dev >$APP_HOME/logs/startup.log 2>&1 &
测试项目如下,忽略错别字:
开发提交代码部署完之后,访问一下正常的功能即可在平台上看见是否存在漏洞。
部分产品同时还会检测第三方组件包。
公司使用harbor来对镜像进行当仓库镜像,项目部署完成之后会打包成一个镜像上传到harbor,harbor自带镜像扫描功能。
测试阶段
开发完成之后进入到测试阶段。这个阶段我们进行静态代码扫描,功能测试,安全测试。
静态代码扫描
利用静态代码扫描工具对代码在编译之前进行扫描,并在静态代码层面上发现各种问题,其中包括安全问题。部分工具列表:
静态代码扫描我们采用sonarQube集成,我们使用的是FindbugSecurity,精简规则,然后在持续构建过程中,进行静态代码bug,安全扫描。
静态代码扫描的同时也可以扫描第三方依赖包,OWSAP的Dependency-Check就可以集成到持续构建过程中,由于IAST类产品支持该功能,不多做介绍。
功能测试
功能测试方面,公司测试部门实现了自动化测试平台,前期我们并未使用agent的方式检测,一开始使用开源的gourdscan加上openrasp,利用openrasp的默认开启不拦截模式和漏洞记录功能来检测服务端无返回的漏洞。
只需要在自动化平台上配置代理IP:
openrasp漏洞记录
后来测试反馈扫描的脏数据太多,效果也并不是很好,就放弃了此方案。改用开发阶段的IAST的插桩方式,同样在测试环境也和开发环境一样利用agent来检测问题。功能测试完成之后。由于测试人员对漏洞并不是太理解,所以定的流程为测试人员到平台查看报告和安全人员沟通哪些问题需要修复,然后将问题写入到测试报告
安全测试
在测试阶段已经将安全加入到整个流程里面,所有需求更改完成都需要通过功能测试,也就是所有的流程过一遍安全测试,这样安全人手也不是很足,决定采用内外服务区分的办法来确定是否需要安全人员介入
漏洞管理
漏洞管理这一块制定了漏洞管理制度,根据影响程度对漏洞进行评级,严重漏洞必须改完之后才能上线,高中低危漏洞且影响较小需要排期,安全人员定期跟踪漏洞修复情况。
五、 监控
支付公司一般安全设备基本都有,这一块基本上将设备的syslog打到日志中心可视化,并定制对应的规则实现告警即可
六、结束语
个人知识和经验不足对sdl的体系并不是很熟悉,没什么经验,所以只能做到目前的程度。后续还有许多地方可以优化,增加流程等。如果有什么好的建议欢迎交流