快速发现安全问题

当前大量的安全测试主要是指手动或者使用某些工具进行安全扫描,渗透测试等。由于渗透测试和安全攻击需要丰富的经验和技术,而使用特定的工具来进行安全扫描和渗透测试也需要特殊的技能,导致安全测试只有少量专业人员才可以做。其实常规的安全测试是可以借助大量的工具以自动化的方式进行,并且可以集成入CI服务器,从而让开发团队中的所有人员都可以在CI流水线完成之后第一时间发现软件系统的常规安全问题,从而不必等到上线前由安全专家来发现安全问题,再来加班修复。

其中自动化安全测试主要包含以下部分:

1. 静态代码扫描

通过人工评审来发现代码中的安全问题的成本非常高,并且随着项目代码规模的增加,评审难度和成本也随之增加。所以可以利用静态代码扫描工具自动的对代码进行扫描,在静态代码层面上发现各种问题,其中包括安全问题。而且自动化扫描工具可以加入CI服务器,能伴随着流水线进行自动扫描,保证每天提交的代码都能经过安全检查,从而实现快速反馈,降低问题发现的成本和维修成本。

对于案例中的P2P项目,可以使用Fortify统一扫描Android,iOS和Web系统的所有代码。但是由于Fortify等类似的静态代码安全扫描工具会发现很多各种级别的安全漏洞,所以评审漏洞需要花费一些时间。如果项目成本优先,可以先只关注高危漏洞,有些低优先级的漏洞可以暂缓修复。

2.动态安全扫描

静态代码扫描可以发现代码中的安全问题,但是当软件系统的各个组件集成到一起之后或者系统部署到测试环境后,仍然可能会产生系统级别的安全漏洞,比如XSS,CSRF等安全问题,所以在这个时候对系统进行动态安全扫描可以在最短的时间内发现安全问题。动态扫描一般分为两种类型:主动扫描和被动扫描。

虽然自动扫描工具可以发现大部分基本的安全漏洞,比如XSS,CSRF等,但是它不能发现业务逻辑、身份认证以及权限验证等相关的安全漏洞,而对于这些类型的漏洞则需要开发相应的自动化安全功能测试。

在P2P项目里面,首先可以使用ZAP和SQLMap对Web应用和Web Service API进行被动安全扫描和SQL注入扫描;其次根据业务分析和威胁建模中得到的Evil Scenarios,使用Calabash在Android和iOS应用上对Evil Scenarios进行自动化测试,而对于Web应用则使用Selenium编写自动化安全测试。最后,在项目流水线里面嵌入这些自动化扫描和测试,从而保证代码提交以后可以持续性的自动运行这些安全扫描和测试。

3.依赖扫描与监控

由于当前应用依赖的第三方库和框架越来越多、越来越复杂,比如SSL、Spring、Rails、Hibernate、.Net,以及各种第三方认证系统等,而且系统开发的时候一般选定某个版本后,在很长一段时间内都不会主动去更新,因为更新的成本一般都比较高,比如新库和新框架更改了API的使用方法和使用流程,可能导致系统进行大规模重构。但是往往这些依赖为了添加新的功能和修复各种当前的问题——包括安全问题,却会经常发布新版本。这些依赖库和框架的安全问题只要被发现,通常都会被公布到网上,比如CVECWE乌云等,导致很多人都可以利用这些漏洞去攻击使用这些依赖的系统。

依赖扫描就是通过扫描当前应用使用到的所有依赖(包括间接依赖),并和网上公布的安全漏洞库进行匹配,如果当前某个依赖存在某种危险级别(需要自己定义)的漏洞,就立即发出警告(比如阻止CI编译成功等)来通知开发人员或者系统管理员,从而在最短的时间内启动应对措施,修复这个问题,达到防止攻击,避免或者减少损失的目的。

在P2P项目里面,可以使用OWASP Dependency Check来自动扫描Android应用和Web服务器系统的第三方依赖库是否存在安全漏洞,然后加入到流水线中,并配置为只要检测到高危漏洞,流水线就会失败,阻止生成应用的编译和构建,并发出警告。

图3-1

持续性的自动化安全扫描很主要是替代把以前人工效率最低的那部分,以达到高效的目的。虽然当前绝大部分安全扫描工具并不能发现所有的安全问题,但是它可以在较小投入的情况下持续发现大部分系统的基础安全问题,从而防止大部分中级和几乎所有初级黑客的攻击。但是BSI去不能完全省去人工的工作,比如人工审查自动化安全测试的报告,如果有安全问题,还需要人工分析安全问题等。所以BSI里自动测试的目的不是用自动化来取代人工,而是最大限度的节省人工成本。

所以对于系统的安全,首先要分析系统的安全需求和可用资源,在资源有限的情况下应该首先实施自动化持续安全扫描。如果系统的安全需求很高,并且在资源允许的情况下再投入人工渗透性测试等,从而获得安全上的最高投资回报比。