第 10 章 知识域:软件开发安全
CISP 考试教材《第 1 章 知识域:信息安全保障》知识整理
CISP 考试教材《第 2 章 知识域:网络安全监管》知识整理
CISP 考试教材《第 3 章 知识域:信息安全管理》知识整理
CISP 考试教材《第 4 章 知识域:业务连续性》知识整理
CISP 考试教材《第 5 章 知识域:安全工程与运营》知识整理
CISP 考试教材《第 6 章 知识域:信息安全评估》知识整理
CISP 考试教材《第 7 章 知识域:信息安全支撑技术》知识整理
CISP 考试教材《第 8 章 知识域:物理与网络通信安全》知识整理
CISP 考试教材《第 9 章 知识域:计算环境安全》知识整理
CISP 考试教材《第 10 章 知识域:软件开发安全》知识整理
目录
10.1 知识子域:软件安全开发生命周期
10.1.1 软件生命周期模型
软件开发生命周期(Software Development Life Cycle,SDLC)又称为软件生存周期或软件生命周期
每个阶段都要有定义、工作、审查,并形成过程文档,按部就班、逐步推进,以提高软件的质量
按照软件生命周期思想,软件开发不再单单强调“编码”,而是概括了软件开发的全过程
生命周期模型(Life Cycle Model)
1.瀑布模型
瀑布模型(Waterfall Model)
核心思想是按工序将问题简化,将功能的实现与设计分开,便于分工协作,即采用结构化的分析和设计方法将逻辑实现与物理实现分开
2.迭代模型
迭代模型是统一软件开发过程(Rational Unified Process,RUP)推荐的周期模型
迭代模型可以理解为多个小型的瀑布模型的组合,所有的阶段都可以细分为迭代,每一次迭代都会产生一个可以发布的产品,这个产生是始终产品的一个子集
3.增量模型
增量模型融合了瀑布模型和迭代模型的特征,该模型采用随着日程时间的进展而交错的线性序列,每一个线性序列产生软件的一个可发布的“增量”
4.快速原型模型
快速原型模型又称为原型模型,它是增量模型的另一种形式;它是在开发真实系统之前,构造一个原型,在该原型的基础上,逐渐完成整个系统的开发工作
快速原型是利用原型辅助软件开发的一种思想
5.螺旋模型
螺旋模型是一种演化软件开发过程模型,它兼顾了快速原型的迭代以及瀑布模型的系统化与严格监控的特征
螺旋模型更适合大型的、昂贵的系统级软件应用
6.净室模型
净室是一种应用数学与统计学理论以经济的方式生产高质量软件的工程技术
净室技术“防患于未然”的主导思想
7.各软件过程模型的特点
10.1.2 软件危机与安全问题
1.软件危机
(1)第一次软件危机
这个时代的程序一个典型的特征就是依赖特定的机器,程序员必须根据所使用的计算机的硬件特征编写特定的程序
迫切需要改变软件的生产方式,提高软件的生产效率,第一次软件危机开始爆发
-
软件开发费用和进度失控
-
软件的可靠性差
-
生产出来的软件难以维护
(2)第二次软件危机
当软件规模不断扩大到需要大量的开发人员共同协作时,第二次软件危机就诞生了
-
软件成本在总成本中所占的比例不断升高
-
软件开发生产率提高的速度远跟不上硬件的发展速度,使得人类不能充分利用现代计算机硬件所能提供的巨大潜力
为了解决这次危机,面向对象的编程语言诞生了
更好的软件工程方法诞生了,而程序员也越来越不知道硬件时怎么工作的了
(3)第三次软件危机
代码行越多,缺陷也就越多
软件存在漏洞和缺陷不可避免,这使得应用系统面临极大的安全风险,从而导致了第三次软件危机
-
由于软件安全问题导致的损失越来越多,软件安全性已经成为不得不认真考虑的问题
-
软件开发需求中被加入安全相关的需求,安全性测试成为软件验收的依据之一
为了更好地应对第三次软件危机,在软件开发的生命周期中开始引入安全相关工作,软件安全开发生命周期诞生了
2.软件安全问题
软件安全(即设计、构造和测试安全的软件的方法)
软件安全问题不仅仅是编码问题,数据显示,有超过 50% 的问题实际上属于软件设计方面的问题
软件安全问题的根本原因在于两个方面:一是内因,软件本身存在安全漏洞;二是外因,软件应用存在外部威胁
软件的缺陷的增长速度趋向于与代码行数的平方而变化
软件安全问题产生根源的外因是在目前的软件开发管理中,更多地重视软件功能而不关注对安全风险的管理
3.软件安全保障
软件安全保障是对“软件可以规避安全漏洞而按照预期的方式执行其功能”的信息
软件安全保障是指确保软件能够按照开发者预期、正常地执行任务,提供与威胁相适应的安全能力,从而避免存在可以被利用的安全漏洞,并且能从被入侵和失败的状态中恢复
软件安全保障的目的是在软件开发生命周期中提升软件的安全性,主要目的如下
(1)可信赖性
(2)可预见性
(3)遵循性
10.1.3 软件安全开发生命周期模型
软件安全开发涵盖软件的整个生命周期
安全软件开发生命周期(Secure Software Development Lifecycle,SSDL)是一种强调具有安全设计和安全措施的软件生命周期,即通过软件开发的各个步骤来确保软件的安全性,其目标是最大限度地确保软件的安全
据数据表明,在软件发布后对安全漏洞的修复所需的成本至少是在软件设计和编码阶段就进行修复的 30 倍
1.SDL(安全开发生命周期)
SDL 基于 3 个核心概念:教育、持续过程改进和责任
SDL 将软件开发生命周期划分为 7 个阶段,并提出了 17 项重要的安全活动
弃用不安全的函数,属于实现(实施)阶段
(1)培训
(2)需求
(3)设计
(4)实现
(5)验证
(6)发布
(7)响应
2.CLASP(综合的轻量级应用安全过程)
由安全软件公司(Secure Software,Inc)提出,后来由开放 Web 应用安全项目(The Open Web Application Security Project,OWASP)完善、维护并推广
3.CMMI(软件能力成熟度集成模型)
CMMI 的 5 个级别
(1)CMMI Level 1,初始级
(2)CMMI Level 2,可管理级
(3)CMMI Level 3,已定义级
(4)CMMI Level 4,量化管理级
(5)CMMI Level 5,优化管理级
CMMI 的每个等级都由几个过程域组成,这几个过程域共同形成一种软件过程能力
每个过程域都由一些特殊目标和通用目标
当一个过程域的所有特殊实践和通用实践都按要求得到实施,就能实现该过程域的目标
4.SAMM(软件保证成熟度模型)
软件保证成熟度模型(Software Assurance Maturity Mode,SAMM)
SAMM 规定了 4 个软件开发过程中的核心业务功能,包括治理、构造、验证以及部署
4 个业务功能各包括了 3 个安全实践
(1)治理:策略与指标、教育与指导、政策与遵守
(2)构造:安全需求、威胁评估、安全架构
(3)验证:设计审核、安全测试、代码审核
(4)部署:环境强化、漏洞管理、操作启用
5.BSIMM(BSI成熟度模型)
BSI 成熟度模型(Building Security In Maturity Model,BSIMM)
6.各软件安全开发模型的特点
BSI 认为软件安全有 3 根支柱:风险管理、软件安全接触点和安全知识
Gary McGraw
10.2 知识子域:软件安全需求及设计
安全需求分析应当以风险管理为基础
安全设计内容一般包括系统安全框架、访问控制机制、主体权力和权限、加密方法和算法、数据完整性机制、敏感数据处理机制、内部通信机制等
10.2.1 威胁建模
1.威胁建模作用
威胁建模活动可帮助识别安全目标、相关威胁、相关漏洞和对策
威胁建模也是一种风险管理模型,可以适用于所有的软件产品和系统的开发
2.威胁建模流程
威胁建模主要流程包括四步:确定建模对象、识别威胁、评估威胁和消减威胁
(1)确定建模对象
(2)识别威胁
威胁并不等于漏洞
(3)评估威胁
(4)消减威胁
3.STRIDE 模型
微软提出使用 STRIDE 模型来进行威胁建模的实践,STRIDE 由 Spoofing(假冒)、Tampering(篡改)、Repudiation(否认)、Information Disclosure(信息泄露)、Denial of Service(拒绝服务) 和 Elevation of Privilege(提升权限)的第一个字母组合而成
10.2.2 软件安全需求分析
1.系统调查
了解信息系统所处的安全环境及其他与安全相关的信息
在此基础上确定需要保护的资产
评价各个资产的相对价值
2.定性分析系统的弱点和可能遭受的安全威胁
预测资产可能受到的损害及损害来自何方
系统脆弱点和安全威胁是两个互相依存的概念:没有威胁,就无所谓脆弱点;没有脆弱点,威胁也就不称其为“威胁”
3.脆弱点和安全威胁的定量分析
确定系统暴露各种脆弱点及面临安全威胁的可能性
4.需求的确定
将定性分析和定量分析的结果结合起来以定义信息系统的安全需求
开发人员确定相应的安全措施,达到为信息系统提供有效且合理的安全保障的目的
10.2.3 软件安全设计
1.工作内容与活动
概要设计阶段确定应用系统的安全整体架构
软件安全设计的活动包括以下方面
(1)详细风险评估
(2)控制措施选择
(3)安全技术实现
技术实现分为三步:结构设计、模块设计、详细设计
(4)审计审查
检查安全设计是否符合安全需求
2.安全设计原则
(1)最小特权原则
只应该分配最少的必要权限
(2)权限分离原则
把权限分离成不同的权限许可和认证条件,把用户分离成不同的权限角色
(3)最少共享机制原则
避免多个主体共享同一个资源
避免资源争用
(4)完全中立原则
(5)心理可接受度原则
(6)默认故障处理保护原则
即使丧失了可用性,也应该保障系统的机密性和完整性
(7)经济机制原则
(8)不信任原则
开发者应该假定系统环境是不安全的
(9)纵深防御原则
软件应该设置多重安全措施,并充分利用操作系统提供的安全防护机制,形成纵深防御体系,以降低攻击者成功攻击的机率和危害
(10)保障最弱环节原则
(11)公开设计原则
(12)隐私保护原则
系统收集到的用户信息都必须实施妥善和安全的保护
(13)攻击面最小化原则
攻击面(Attack Surface),通常也称受攻击面,是指对一个软件系统可以采取的攻击方法集合
攻击面越大,其安全风险也就越大
10.3 知识子域:软件安全实现
10.3.1 安全编码原则
CERT 发布的有关 C、C++、Java 等语言的著名安全编码标准
OWASP 发布了《OWSAP 安全编码规范快速参考指南》
1.验证输入
常见的输入源如下:
(1)命令行参数
(2)环境变量
(3)文件及文件名
(4)网络数据
(5)其他来源
2.避免缓存溢出
避免缓冲区溢出,可以使用很多安全防御措施
(1)精心编程避免缓冲区溢出
(2)使用替代的安全函数或函数库
(3)基于探测方法方法,使用更新、更具安全性的编译环境,打开一些具有安全防御机制的选项
Immunix 提供的 StackGuard
OpenBSD 提供的 ProPolice
Microsoft 提供的 /GS 选项
(4)非执行的堆栈防御
为 OpenWall 使用的 non-exec 补丁
Redhat/Fedora 所使用的 exec shield
3.程序内部安全
(1)程序内部接口安全
(2)异常安全处理
(3)最小化反馈
(4)避免竞争条件
(5)安全使用临时文件
4.安全调用组件
为避免调用组件带来安全问题,建议在组件安全、返回值安全以及传递数据安全等几个方面加强安全防护
(1)组件安全
(2)返回值安全
(3)传递数据安全
5.禁止使用不安全函数
10.3.2 软件安全编译
10.3.3 代码安全审核
1.源代码审核的概念和原理
源代码审核是指无须运行被测试代码,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性,报告源代码中的可能导致安全弱点的薄弱之处,找出代码隐藏的错误和缺陷
理想的做法是使用源代码审核工具审核和人工审核结合的方式对代码进行审核,能极大地减少软件中的安全问题被带入随后的软件生命周期阶段的可能性
2.源代码审核工具
开源工具:BOON、Cqual、Xg++ 和 FindBugs 等
商业工具:Fortify、Coverity、CheckMax、Ounce Labs 和 SecureSoftware 等
(1)安全性
(2)多平台性
(3)可扩展性
(4)知识性
(5)集成性
10.4 知识子域:软件安全测试
IEEE 软件测试定义为:使用人工和自动化的手段来运行或测试某个系统的过程,其目的在于检验它是否满足规定的需求或是弄清预期结果与实际结果之间的差异
10.4.1 软件测试
1.软件测试基本概念
(1)测试用例
测试用例是为某个特定目的而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求
(2)测试覆盖率度量指标
测试覆盖率度量指标是测试完整性的一个手段,是测试有效性的一个度量
-
语句覆盖
-
判定覆盖,又称分支覆盖
-
条件覆盖
-
判定-条件覆盖
-
条件组合覆盖
-
路径覆盖
(3)测试的信条
2.软件测试方法
根据软件测试工作的测试策略,一般将软件测试过程分为单元测试、集成测试、系统测试和验收测试 4 个大阶段
根据对软件内部工作过程了解的程度又分为黑盒测试、白盒测试和灰盒测试
从测试过程中是否执行软件又可以将软件测试分为静态测试和动态测试
(1)单元测试、集成测试、系统测试
单元测试是对软件中的基本组成单元进行测试
单元测试的主要方法又控制流测试、数据流测试、排错测试等
集成测试是在软件集成过程中所进行的测试,其主要目的是检查软件单位之间的接口是否正确
系统测试是对已集成好的软件系统进行彻底的测试
(2)黑盒测试、白盒测试、灰盒测试
黑盒测试意味着测试要在软件的接口处进行(外部人员)
黑盒测试又称功能性测试或数据驱动测试
白盒测试也称结构测试、透明测试、逻辑驱动测试或基于代码的测试,是对软件的过程细节做的细致的检查(内部人员)
灰盒测试是一种介于白盒测试和黑盒测试之间的一种测试方法(两者之间)
(3)静态测试、动态测试
静态方法是指不运行被测程序本身
静态测试又可分为代码走查、代码审核和代码评审
-
代码走查
-
代码审查
-
代码评审
动态方法是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效果和健壮性等
(4)回归测试
回归测试是指在发生修改之后重新测试先前的测试以保证修改的正确性
(5)验收测试
验收测试旨在向购买者展示该软件系统满足其用户的需求
这是软件在投入使用之前的最后测试
10.4.2 软件安全测试
1.软件安全测试基本概念
2.软件安全测试方法
模糊测试和渗透测试是常用的软件安全性测试方法
(1)模糊测试
模糊测试,也称 Fuzz 测试
一种通过提供非预期的输入并监视异常结果来发现软件故障的方法
模糊测试的主要步骤
-
生成大量的畸形数据作为测试用例
-
将这些测试用例作为输入应用于被测对象
-
检测和记录由输入导致的任何崩溃或异常现象
-
查看测试日志,深入分析产生崩溃或异常的原因
影响模糊测试效果的一些关键因素
-
测试点
-
样本选择
-
数据关联性
-
自动化框架
-
异常监控与异常恢复
-
分析评估
(2)渗透测试
渗透测试是一种模拟攻击者进行攻击的测试方法,从攻击的角度来测试软件系统,并评估系统安全性的一种测试方法
渗透测试会使用多种网络安全工具,自动化的渗透测试平台也逐渐出现,比较著名的包括 IMPACT、CANVAS 和 Metasploit
开展渗透测试必须注意以下两点
-
它是非破坏性测试
-
需要进行测试风险控制
(3)静态代码安全测试
3.安全测试思路
做好软件安全性测试的必要条件
(1)充分了解软件安全漏洞
(2)评估软件安全风险
-
安全性缺陷数据评估
-
采用漏洞植入法来进行评估
(3)拥有高效的软件安全测试技术和工具
10.5 知识子域:软件安全交付
10.5.1 软件供应链安全
1.软件供应链安全的概念
不同于自身的安全漏洞,供应链安全问题来自外部的恶意代码对软件代码的污染
这些安全问题设计软件的代码编写、代码编译、软件分发、软件更新等各个环节
(1)代码编写
针对共享库进行攻击,攻击者能将恶意代码植入这些共享库中,从而随着软件的发布进入最终的用户计算环境中
(2)代码编译
实施编译的软件如果被攻击者植入了恶意代码
(3)软件分发及更新
攻击者入侵了软件开发商的系统,在发布/更新的软件中嵌入恶意代码,利用用户对软件开发商的信任进入用户的系统中,从而给用户带来安全风险
2.软件供应链安全应对措施
针对供应链安全问题的根源采取措施才是有效解决之道
(1)代码编写安全
(2)代码编译安全
(3)软件发布及更新安全
10.5.2 软件安全验收
10.5.3 软件安全部署
由于软件安全加固和配置上的错误导致的安全问题在软件安全问题中占比非常高