软件全生命周期安全性测试方法研究
2013-01-27尹党辉
尹党辉,赵 颖,董 超
(总后勤部后勤科学研究所,北京 100071)
0 引 言
安全性,是软件质量属性的重要方面,是软件受到恶意攻击时仍能提供所需功能的能力[1],避免造成不可接受风险的能力。
软件安全性测试,是验证软件的安全功能和识别潜在安全性缺陷的过程,是排除软件中可能引发严重后果的错误、降低软件安全风险[2]的重要手段。安全性测试不同于其他测试类型,它强调的是软件不可以做什么。
软件安全性测试可分为安全功能验证和安全漏洞检测两个方面[3]。安全功能验证重点关注需求设计是否全部得到了实现和需求设计的要求是否一致,实现的功能运行是否正确无误。软件安全功能需求通常包括数据安全、用户管理、访问控制、传输安全等方面。安全漏洞测试,则是站在攻击者角度去识别软件可能存在的安全漏洞。所谓安全漏洞,是指软件在设计、实现、应用和管理过程中存在的可被利用的缺陷。这些漏洞一旦在软件投产后被攻击者利用,即可使软件进入不安全状态,造成一系列损失,因此安全漏洞检测也是软件安全性测试的一个重要方面。
1 常见的软件安全性问题
软件安全性问题多种多样,本文介绍4类应用中最为常见的问题及其产生原因。
1.1 缓冲区溢出
缓冲区溢出安全性问题通常由两种情况引发:(1)设计空间不足,合法数据进入时,由于程序实现层内对应的设计空间不足,导致程序处理时出现溢出;(2)缺乏对数据的校验,非法数据没有在外部输入层被检查出来并丢弃,导致非法数据进入接口层和实现层,因超出对应的空间范围,从而引起溢出。
1.2 突破数据加密
引起数据加密安全性问题[4]的因素很多,主要有:加密算法强度不够,甚至应用穷举法即可破解;用存在缺陷的伪随机算法产生数据加密密码,导致密码易被破解;客户机和服务器时钟未严格同步,攻击者可抓住时间差破解密码或破坏数据等。
1.3 用户权限问题
权限设计[5]分配不当,或实现后存在可突破漏洞,将可能导致只有普通用户权限的恶意用户利用过大的权限做出危害安全的操作,访问超出规定范围的其他资源。
1.4 利用错误处理信息
软件在对错误操作进行处理时,为提高用户体验,通常都会给用户返回一些信息,这些错误处理信息可能会被某些恶意用户利用来实施攻击。
2 软件安全性测试方法
针对软件全生命周期的安全性测试方法主要有以下4个方面。
2.1 软件需求安全性
用户需求是软件产品成败的根本,所以在产品研发的需求分析阶段就应纳入安全性需求考虑,提出必要的软件安全功能、安全策略和安全完整性要求。
在此阶段,测试人员应根据软件安全性需求分析的结果和初步的结构设计文档,包括分配的功能需求、接口需求以及隐含需求[6],对产品安全性需求进行映射,形成软件安全测试需求分析报告,该报告应经过用户和产品设计人员的认可。测试人员依据该报告,综合分析安全性需求的合理性、可行性、全面性,发现可能存有的漏洞,提出修改意见,还可以提出对后续软件设计阶段的建议。例如,某软件需求分析阶段没有明确定义用户权限,测试人员在需求分析阶段的安全性测试中发现并提出,产品设计人员及时补充完善此部分功能定义,可避免产品应用后出现的权限问题。
2.2 软件概要设计安全性
软件概要设计是制定软件基本安全性策略的阶段,负责定义主要软件部件,以及它们如何交互,如何获得所要求的安全属性,特别是安全完整性,是软件安全性需求在结构定义中实现的阶段。通常,数据加密算法会在软件概要设计中进行基本明确。对概要设计进行安全性测试要做到将全部软件安全性需求综合到软件的体系结构设计中,确定结构中与安全性相关的部分,并评价概要设计的安全性。
概要设计是开发人员对系统期望功能和功能实现方式的表示方法,设计的合理性,通常会影响到安全完整性。测试员应根据软件概要设计安全策略,设计测试项和测试用例。验证软件安全策略的有效性,通常应采用有效类和无效类的方法设计测试用例,用动画/仿真技术证实功能的实现状态,借助接口分析技术分析安全相关部件与其他部件的相互依赖关系和独立性。这一阶段测试员应熟悉软件的安全策略及实现方式,有针对性地设计测试用例。
2.3 软件详细设计安全性
软件详细设计进一步细化高层的体系结构设计,将软件结构中的主要部件划分为能独立编码、编译和测试的软件单元,并进行软件单元的设计。
在这一阶段中,测试员需要依据软件需求、结构设计描述、软件集成测试[7]计划之前所获得的软件安全性分析的结果,对软件的设计和实现阶段是否符合软件安全性需求进行验证。
测试员应该仔细分析:(1)软件详细设计是否已覆盖了软件安全性需求;(2)软件详细设计是否与软件概要设计保持了外部一致性;
(3)软件详细设计是否满足模块化、可验性、易安全修改的要求。
软件详细设计既是对软件需求的具体细化,又是程序编码的最直接依据。常见的错误处理安全缺陷和用户权限过大或过小漏洞等会出现在此阶段。对于软件处于边界条件下的安全性,是软件在详细设计中常常被忽略的环节,软件的边界存在于接口、数据、时间、状态等方面。在测试过程中必须对边界、界外及边界结合部进行分段测试。软件详细设计安全性分析更关乎整个软件的安全性。软件详细设计安全性常见的安全性测试手段和技术有设计逻辑分析、设计约束分析和复杂性度量。
设计逻辑分析:评价软件设计的方程式、算法和逻辑,可以包括失效检测/诊断、冗余管理、变量报警和禁止命名逻辑的检测。
设计约束分析:给出一些约束,来评价软件在这些约束下运行的能力。比如:物理时间约束和响应时间对软件性能的检查。
复杂性度量:高度复杂的数据结构难以彻底测试,可以采用McCabe或Halstead等这样一些复杂性评估技术来标示出需要进一步改进的区域。
2.4 软件编码安全性
软件编码完成软件详细设计的实现。所以,代码应该体现软件详细设计所提出的设计要求,实现设计过程中开发的安全性设计特征和方法,遵循设计过程中提出的各种约束以及编码标准。
测试员一般采用代码走查或静态检查工具来检查源代码,主要从以下两个方面分析:
(1)分析软件代码是否满足模块化、可验证、易安全修改的要求;
(2)分析软件编码中所使用技术的安全性和方法的合理性。
常见的代码安全性测试技术有代码逻辑分析、代码数据分析和复杂性度量。
代码逻辑分析[8]:如有不可达代码,或代码结构过于复杂,维护性降低。通过实施逻辑重构、方程式重构和存储器解码来进行。
代码数据分析:关注如何定义和组织数据项。变量忘记赋初值,或变量声明了却没有使用,或出现了冗余代码。
复杂性度量:复杂软件不稳定,也经不起不可预测的行为。所以,努力使软件的复杂度变小。如果有条件采用某种自动化工具,可以通过工具对软件设计/用代码进行控制,用图形化的方法反映出软件结构中的控制流和数据流,通过连结数/调用数、节点数、嵌套深度等这样一些结构关系的检查,获得复杂度的度量,将会获得很好的效果。
3 结束语
经过多年的软件测试实践,软件测试作为验证软件功能性和安全性的重要手段,其采用的测试方法和测试技术影响着测试结果,关系着后续软件的变更和测试的有效性,一些测试经验和猜错法也是十分必要的。软件测试安全性分析既包括事前分析,也包括对测试结果的评价,对测试结果进行分析,以验证所有的安全性需求是否得到了满足。在执行任何软件变更之前,应建立软件变更规程。如果必须进行软件变更,则应该对已经受控的规格说明、需求、设计、编码、计划、规程、系统、环境、用户文档的任何变更都进行安全性分析。
[1]McGraw Gary,Potter Bruce.Software security testing[J].IEEE Security&Privacy,2004,2(5):81-85.
[2]刘学敏,周经伦,罗鹏程.基于小世界网络的软件安全风险传播分析[J].江苏大学学报,2011,32(1):89-93.
[3]施寅生,邓世伟,谷天阳.软件安全性测试方法与工具[J].计算机工程与设计,2008,29(1):27-30.
[4]任德昊,吴少华,颜开.局域网中的数据安全问题研究[J].中国民航飞行学院学报,2005,16(5):28-31.
[5]吕宜洪,宋瀚涛,龚圆明.大型应用系统用户权限构成分析及访问控制策略研究[J].小型微型计算机系统,2004,25(2):195-198.
[6]Jorgensen P C.软件测试[M].2 版.韩柯,杜旭涛.译.北京:机械工业出版社,2003.
[7]尹党辉,连尧,董超.嵌入式软件测试技术研究[J].中国测试,2011,37(z):74-77.
[8]尹党辉,于佳伟,李虎.软件覆盖测试技术研究[J].中国测试,2012,38(z):42-44.