写点什么

在 CI 中实现持续 Web 安全扫描

  • 2015-06-14
  • 本文字数:4645 字

    阅读完需:约 15 分钟

一. 当前 Web 应用安全现状

随着中国互联网金融的爆发和繁荣,Web 应用在其中扮演的地位也越来越重要,比如 Web 支付系统、Web P2P 系统、Web 货币系统等。对于这些金融系统来讲,安全的重要性是不言而喻的, 一旦黑客利用安全漏洞入侵系统后,损失的不仅仅是数据,还包括企业或者客户的财产。

国内著名的乌云漏洞平台,每天都会爆出十几条甚至几十条各大网站的安全漏洞,比如:

  • 中国电信某省任意用户登陆 (可恶意扣费)
  • 中石化某销售物流系统后台远程命令执行的服务器沦陷 (客户信息泄漏 && 可内网渗透)
  • 盛大某游戏总管理权限泄露可随意更改游戏玩家数据
  • 招商银行某服务器存在漏洞可 Shell(穿透边界防火墙连通内网)

这里面包括了通信、金融、银行、能源、游戏等各个行业的 Web 应用的各种漏洞,有一些已经造成了影响广泛的严重安全事件,例如:CSDN、12306、小米用户信息泄露事件,携程网信息安全门事件、某快递官网遭入侵 1400 万条用户信息被转卖等等。

对于很多公司而言软件系统安全关注的重点还在网络和操作系统层面上,比如配置昂贵的网络入侵检测系统以等;很多开发人员安全意识薄弱,比如使用直接在代码中组装 SQL 语句,使用简单的数据加密和认证的方案,使用弱口令以及在产品中嵌入一些特定的调试信息;很多测试人员也不会进行基于业务流程的安全测试;系统管理和运维人员对于不可预知的应用组件和依赖的安全漏洞无法及时发现和修补。很多中小型公司基本不可能对于 Web 安全投入太多,比如无法在开发的过程中持续关注安全问题,从而导致系统上线之后还存在很多问题。因此,开发、测试和运维人员能充分理解安全的重要性以及掌握自动化安全扫描的方法和工具,对于开发一个安全的 Web 系统至关重要。

针对 Web 应用如此多的安全问题,全球范围内的有志之士成立了 OWASP (Open Web Application Security Project),致力于宣传各种 Web 应用的安全问题。以及如何扫描、防御等知识,并且每 2~3 年还会发布世界范围内排名前十的安全问题。虽然OWASP 提供如此丰富的安全知识,但是很多开发团队并没有充分利用,有些甚至还不知道,有些知道却不愿意投入。各种原因导致当前中国互联网上的众多Web 应用拥有大量安全问题。

二. 持续安全扫描

面对当前如此复杂和危险的互联网环境,如果一个在线金融系统(比如网银,P2P 金融)存在安全问题,而系统管理员又没有及时发现安全问题和修复,那么时间越久,攻击者对其利用的程度越高,系统遭受的损失越大。这些安全问题可能是系统本身业务设计或者编码遗留的问题,也可能是依赖的第三方组件或者服务的问题。对于一些金融系统,修复安全漏洞哪怕只是晚几个小时,损失也可能是巨大的。如果不及时发现系统的安全问题并及时修复,那么开发成本和系统损失随着时间的推移可能会成指数级的增长。所以尽早发现安全问题并修复是节省成本和避免损失的有效方法。

对于软件安全,当前许多企业只会在发布或者上线之前进行一次渗透测试,如下图:

这种一次性的解决方案存在很多问题。其结果的有效性很难保证,如果发现问题可能会严重拖延发布时间等。为了解决它们,可以引入内建开发流程-BSI(Build Security In),如下图:

其中自动化的静态代码扫描,动态系统扫描,依赖扫描以及初级的渗透测试都可以比较容易的在CI 中实现。示意图如下:

1. 静态代码扫描

利用静态代码扫描工具对代码在编译之前进行扫描,并在静态代码层面上发现各种问题,其中包括安全问题。部分工具列表:

利用动态安全扫描工具在系统部署之后对运行中的系统进行安全扫描。

2. 动态安全扫描

动态扫描一般分为两种类型:主动扫描和被动扫描。

  • 主动扫描是首先给定需要扫描的系统地址,扫描工具通过某种方式访问这个地址,如使用各种已知漏洞模型进行访问,并根据系统返回的结果判定系统存在哪些漏洞;或者在访问请求中嵌入各种随机数据(模糊测试)进行一些简单的渗透性测试和弱口令测试等。对于一些业务流程比较复杂的系统,主动扫描并不适用。比如一个需要登录和填写大量表单的支付系统,这个时候就需要使用被动扫描。
  • 被动扫描的基本原理就是设置扫描工具为一个 Proxy Server,功能测试通过这个代理服务访问系统,扫描工具可以截获所有的交互数据并进行分析,通过与已知安全问题进行模式匹配,从而发现系统中可能的安全缺陷。一般在实践中,为了更容易地集成到 CI,会在运行自动化功能测试的时候使用被动扫描方法,从而实现持续安全扫描。示意图如下:

部分工具列表:

3. 依赖扫描与监控

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

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

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

部分工具列表:

三. 在CI 中实现自动化安全扫描

将这三种类型的自动化安全扫描实践集成到CI 服务器中就可以实现对系统的持续性安全扫描。

1、在项目构建阶段进行依赖扫描与监控

对项目使用到的依赖进行安全扫描和监控是非常必要的,而将这一过程自动化能够进一步加强它的效果。这里以 OWASP Dependency Check 为例,介绍如何在项目构建阶段进行依赖扫描和监控。OWASP Dependency Check 是一款开源免费的自动化依赖扫描工具,它由 OWASP 开发并维护,使用 NVD CVE 作为漏洞数据源,自动识别依赖并扫描其是否存在安全问题。它提供 Shell 脚本、Ant 插件、Maven 插件和 Jenkins 插件。

以 Maven 插件为例,首先在 pom.xml 文件里添加这个插件 。

然后使用 Maven 对项目进行构建,OWASP Dependency Check 插件会自动识别项目的依赖(包括间接依赖),对其进行安全扫描并生成报告。

在 Jenkins 中运行扫描并保存安全报告的配置如下:

下面的扫描报告中列出了 Struts2 和 commons-fileupload 两个依赖存在安全漏洞,以及严重程度等信息,如下图:

如果项目没有使用 Maven, OWASP Dependency Check 还提供 Jenkins 插件,同样能对依赖进行扫描,但这种方式需要明确指定所需扫描依赖的目录或者文件名,Jenkins 配置如下:

OWASP Dependency Check 以自动化的方式对项目的依赖进行扫描,极大的降低了人力成本、提高了效率。不过目前它仅能扫描 JAVA 和.NET 项目的依赖,针对 Node.JS、客户端 JavaScript 库的支持还处于计划阶段。另外,目前它没有提供 Gradle 的插件,如果您的项目使用的是 Gradle,则只能用命令行的方式来运行它。

2、在自动化测试阶段进行被动方式的动态安全扫描

针对 Web 应用的安全扫描工具非常多,其中 OWASP ZAP 是免费软件里面最为常用的。虽然 OWASP ZAP 官方并没有提供相应的方案和构建系统以及 CI 进行集成,但是有一些第三方的开源工具可以帮助其集成。下面将以 Gradle 项目为例,介绍如何在 CI 自动化测试阶段集成 ZAP 并进行被动方式的动态安全扫描。

第 1 步:下载安装 ZAP。

第 2 步:在 Gralde 构建脚本中配置 security-zap 插件用于集成 ZAP。

第 3 步:配置 WebDriver,为其设置代理。

默认配置下,security-zap 插件在启动 ZAP 之后,ZAP 会侦听本地 7070 端口,因此需要将 WebDriver 的代理设置为 localhost:7070,参见示例代码 18。

第 4 步:启动 ZAP 并运行测试。

使用 zapStart 命令来启动 ZAP,用 build 来运行一次构建,在运行所有测试的同时进行被动扫描,命令如下:

<span>gradle zapStart build -Dzap.proxy</span>=<span>localhost:7070</span>> 第 5 步:生成安全报告。

在所有的测试都执行完毕后,使用 zapReport 命令生成报告,命令如下:

gradle zapReport它会在项目根目录下新建一个名为 zap-reports 的目录,并将安全扫描报告放置其中。下面是一份示例安全报告,它列出了所测试的 Web 应用的安全漏洞,按照严重程度以及类别进行了统计,还包含了每个安全漏洞的细节信息,报告如下:

第 6 步:关闭 ZAP。命令如下:

gradle zapStop> 第 7 步:Jenkins 集成。Jenkins 配置如下:

3、在测试环境部署阶段进行主动方式的动态安全扫描

继续以 Gradle 项目和 OWASP ZAP 为例,在安装好 ZAP 并且在构建脚本里配置好 security-zap 插件后(同上一阶段的步骤 1、2), 只需要使用 zapStart 和 zapScan 命令就可以启动主动式扫描,命令如下:

gradle zapStart zapScan主动扫描的检查能力更强,可以弥补被动扫描的不足,但缺点是耗时长,以及在扫描需要身份验证的系统的时操作复杂。

默认配置下主动扫描启动后,security-zap 插件会主动检测扫描进度,默认扫描等待时间为 60 分钟。如果主动式安全扫描的执行时间超过了这一时间,security-zap 会因为超时而终止运行,不过 ZAP 安全扫描并不会因此而停止,它还将继续运行,直到完成所有的安全扫描为止。若要了解当前扫描进度,可以通过运行 zapScanStatus 命令查询,命令如下:

gradle zapScanStatus扫描完成后,通过运行下面的命令生成安全扫描报告,并关闭 ZAP:

gradle zapReport zapStop四. 总结

自动化持续 Web 安全扫描是一个复杂的课题,很大程度上依赖于自动化 Web 安全扫描工具的能力。当前绝大部分 Web 安全扫描工具并不能发现所有的安全问题,就算 OWASP TOP10 也无法全部包括,但是它可以在较小投入的情况下持续发现大部分 Web 系统的基础安全问题,从而防止大部分中级和几乎所有初级的黑客攻击。如果需要更高级别的安全保障,人工渗透性测试和威胁建模等必不可少,但是成本也是相对较高的。

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


刘冉,ThoughtWorks 高级软件质量咨询师, 超过 10 年软件开发和测试工作经验。熟悉嵌入式系统开发、Linux 系统开发、各种脚本、测试工具、自动化测试系统开发、以及 Agile 中的 QA。对服务器性能测试、Web 功能测试,以及测试分层一体化解决方案有较深的理解。现在关注于全方位自动化 QA 的工作,包括自动化安全扫描。

马伟,ThoughtWorks 高级软件开发咨询师,长期从事企业级软件开发工作,拥有丰富的 Web 应用开发经验。熟悉 Java、C#、Ruby、JS、HTML 等前、后端开发技术,在工作中积累了丰富的 Web 应用安全经验。目前专注于安全技术的创新与实践,热衷于探索和研究各种 Web 应用漏洞,对如何将安全实践集成到敏捷开发流程中有浓厚的兴趣和深入的实践,同时也是敏捷软件开发的实践者。

感谢张凯峰对本文的策划,魏星对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-06-14 05:4412024

评论

发布
暂无评论
发现更多内容

基于 Docker 实现 MySQL 主从复制

ytao

MySQL Dockerfile

架构师训练营第二周总结:软件开发简史和框架设计的方法

hifly

设计模式 极客大学架构师训练营

如何高效开会?

石云升

高效工作 时间管理 高效 开会

架构师训练营作业 --Week2

吴炳华

极客大学架构师训练营

依赖倒置原则理解

Thrine

架构师训练营-week2命题作业

J.Smile

极客大学架构师训练营

Spring BeanPostProcessor 你不能不知道的事

CoderLi

Java spring 程序员 源码分析 后端

Libra教程之:Libra testnet使用指南

程序那些事

比特币 区块链 以太坊 libra blockchain

第二周总结

changtai

第二周作业

大雄

依赖倒置

重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」

小傅哥

设计模式 小傅哥 重构 代码优化

[Redis源码阅读]redis持久化

老胡爱分享

数据库 redis 缓存 持久化

2020年6月17日 MySQL基准测试

瑞克与莫迪

面向对象设计原则

陈皮

原创 | TDD工具集:JUnit、AssertJ和Mockito (二十二)编写测试-超时

编程道与术

Java 编程 TDD 单元测试 JUnit

「架构师训练营」第 2周作业

旭东(Frank)

架构 极客大学架构师训练营

为什么 Vue 更符合这个时代的大势所趋

葡萄城技术团队

Vue SpreadJS

程序员开发色情游戏,赴日寻找AV女优真人拍摄,结果...

程序员生活志

程序员 游戏开发

【架构师第二周】总结

浪浪

Libra教程之:来了,你最爱的Move语言

程序那些事

比特币 区块链 以太坊 libra blockchain

Libra教程之:运行自定义move modules

程序那些事

比特币 区块链 以太坊 libra blockchain

【架构师训练营】第2周总结

花生无翼

极客大学架构师训练营

「架构师训练营」第2周作业 - 设计原则

guoguo 👻

极客大学架构师训练营

架构师训练营第二周总结

极客大学架构师训练营

听说你 ping 用的很 6 ?给我图解一下 ping 的工作原理

小林coding

面试 计算机网络 计算机基础

Redis系列之扫盲篇(一)

z小赵

Java 分布式 高并发系统设计

0616作业2

Geek_10

架构师训练营-第二周-作业1

狂奔嘀兔纸

极客大学架构师训练营

学习一下:我的学习之道

非著名程序员

学习 程序员 程序人生 提升认知

一款开源的Diffy自动化对比测试框架:超详细实战讲解

狂师

开源 测试 测试驱动开发实战营 自动化测试

BAT面试题汇总:分布式+Dubbo +JVM+微服务+多线程+Spring附答案(建议收藏)

程序员生活志

Java spring 面试 分布式 mybatis

在CI中实现持续Web安全扫描_安全_刘冉_InfoQ精选文章