标题：软件开发与项目管理专业
基本信息
专业名称：软件开发与项目管理
培养目标
本专业培养具备软件设计、项目管理相关知识，掌握主流的编程技术，具有组织协作等综合素质，从事软件开发与项目管理的应用型人才。
课程设置
主要课程|：C/C++程序设计、数据库原理、JAVA程序设计、WEB程序设计、J2EE、信息系统分析、软件测试技术、软件过程与改进管理、IT项目管理、UML建模。 就业前景 从事Java、.net等平台的应用软件开发，软件系统分析与设计，软件项目配置管理，软件项目组织与管理等方面的工作。
概述
信息系统的许多的安全控制或其他安全性保证是通过系统的开发设计予以实现的。因此如果在系统的开发设计阶段没有对系统的安全性给予充分的考虑，那么系统本身一定会存在许多先天不足，系统就会漏洞百出。为确保应用系统的安全，在应用系统开发之前就应确认系统的安全需求，并以此作为开发设计的阶段的基础。
本规范主要规定了在系统开发的各个阶段所应遵守的各种安全规范，从需求分析开始，到设计，再到开发和维护以及最后的文档等系统开发的各个阶段分别进行阐述，并将在不同阶段中所需要注意的安全问题和相关的安全规范进行进一步的描述和规定。
目标
保护应用系统开发过程的安全。具体地说就是保护应用系统开发过程免受未经授权的访问和更改，保护系统开发中系统软件和信息的安全，确保开发项目顺利正确的实施并对开发环境进行严格的控制。同时确保应用系统开发外包中的各项安全。
适用范围
本套规范适用的范围包括了整个应用系统开发过程中的安全。包括了系统开发可行性和需求分析阶段的安全，系统设计阶段的安全，系统开发阶段的安全，系统测试阶段的安全，系统培训和文档阶段的安全以及系统开发外包的安全规范。
主要规定了应用系统开发过程的安全保密，软件的质量的要求，系统和业务需求的符合性，保证敏感信息的安全，系统本身的稳定性和兼容性问题。
规范引用的文件或标准
下列文件中的条款通过本标准的引用而成为本标准的条款。凡是不注日期的引用文件，其最新版本适用于本标准。
GB17859-1999 计算机信息系统安全保护等级划分准则GB/T 9387-1995 信息处理系统 开放系统互连基本参考模型（ISO7498 :1989）GA/T 391-2002 计算机信息系统安全等级保护管理要求ISO/IEC TR 13355 信息技术安全管理指南NIST信息安全系列——美国国家标准技术院英国国家信息安全标准BS7799信息安全基础保护IT Baseline Protection Manual (Germany)BearingPoint Consulting 内部信息安全标准RU Secure安全技术标准信息系统安全专家丛书Certificate Information Systems Security Professional
术语和定义
访问控制access control 一种安全保证手段，即信息系统的资源只能由被授权实体按授权方式进行访问，防止对资源的未授权使用。应用系统 application system认证 authentication a. 验证用户、设备和其他实体的身份； b. 验证数据的完整性。授权authorization 给予权利，包括信息资源访问权的授予。可用性availability 数据或资源的特性，被授权实体按要求能及时访问和使用数据或资源。缓冲器溢出 buffer overflow指通过往程序的缓冲区写超出其长度的内容，造成缓冲区的溢出，从而破坏程序的堆栈，使程序转而执行其它指令，以达到攻击的目的。保密性confidentiality 数据所具有的特性，即表示数据所达到的未提供或未泄露给未授权的个人、过程或其他实体的程度。隐藏通道 covert channel 可用来按照违反安全策略的方式传送!数据的传输信道。完整性integrity在防止非授权用户修改或使用资源和防止授权用户不正确地修改或使用资源的情况下,信息系统中的数据与在原文档中的相同，并未遭受偶然或恶意的修改或破坏时所具的性质。敏感信息 sensitive information 由权威机构确定的必须受保护的信息，因为该信息的泄露、修改、破坏或丢失都会对人或事产生可预知的损害。系统测试 system testing用于确定系统的安全特征按设计要求实现的过程。这一过程包括现场功能测试、渗透测试和验证。后门代码 trapdoor 通常为测试或查找故障而设置的一种隐藏的软件或硬件机制，它能避开计算机安全。而且它能在非常规时间点或无需常规检查的情况下进入程序。特洛伊木马Trojan horse 一种表面无害的程序，它包含恶性逻辑程序，导致未授权地收集、伪造或破坏数据，以此破坏计算机安全与完整性的进程。验证 verification 将某一活动、处理过程或产品与相应的要求或规范相比较。例：将某一规范与安全策略模型相比较，或者将目标代码与源代码相比较。压力测试 于确定系统的薄弱环节，确定系统在非正常条件下能够迅速恢复到正常的运行状态的能力。
应用系统开发总体原则
应用系统的开发应遵循一系列的总体原则，以确保开发过程中的安全。其中包括：
系统开发应从业务需求的角度出发，不得盲目追求系统的先进性而忽略了系统的实用性。系统的开发是为了更好地满足业务上的需要，而不是技术上的需要。开发的方法和管理必须规范化、合理化、制度化，从而确保开发的质量和进度。应保证开发的进度并按时完成。确保开发工作及时、有效且高质量的完成。系统开发必须具有一定的前瞻性，符合主流系统的发展方向。提高和加强开发人员的安全意识。确保机密信息和关键技术不会泄漏，特别是不可泄漏到竞争对手的手中，否则将会对公司的竞争力产生极大的影响。应充分利用现有的资源。系统需求收集和分析阶段
可行性研究分析
对于应用系统开发项目应进行一定的可行性分析，以保证只有在确认具备了相当的资源和条件，并且有能力满足业务上的需求的情况下才能开展开发工作。切忌盲目开发，否则既浪费资源，又浪费时间。
可行性研究宜从技术、需求面、投入和影响四个方面进行考虑：
技术可行性分析根据业务上提出的需求，从技术开发的角度分析现有的技术手段和技术能力是否能够实现业务上所要求的系统功能。通常可从以下三个方面进行分析：
人员技术能力分析，指公司内的系统开发队伍或外包的第三方开发公司是否具有足够技术和管理能力来完成系统开发的任务。计算机软件和硬件分析，指公司现有的软件和硬件的性能是否足够满足开发相应的系统的要求。管理能力分析，指现有的技术开发管理制度和管理流程是否成熟且标准化，是否满足系统开发的要求。需求可行性分析系统的开发来源于业务上的需求，因此需要对该需求进行可行性分析，以判断需求是否明确，是否符合实际，是否在一定的时间范围内可以实现。
投资可行性分析根据业务需求和技术手段的分析，确认实现系统开发所需的投资，并确认投资的数额是否在可控制和可承受的范围内。
影响可行性分析所谓的影响是指社会影响，比如系统开发是否符合法律法规上的要求，是否和相关的管理制度或行业标准相抵触，是否符合人文或道德上的约束等。
开发人员安全管理
系统开发人员职责分配在系统开发的过程中，应明确不同人员的身份和职责。在系统开发过程中具体可分以下三种角色：
项目负责人员：确保在整个系统开发的各个阶段都实施了相关的安全措施，同时在整个系统开发的过程中负责整个项目的开发安全管理。系统开发人员：根据业务需求确保开发的系统能够满足业务上的需求和相应的安全上的需求，同时满足系统质量上和进度上的要求。系统审核人员：对整个开发的过程进行审核和监督，确保开发的质量和开发的安全。开发人员授权应根据该员工在整个开发项目中所负责的开发内容授予其相应的权限和所应承担的责任。开发人员必须负责其开发内容的保密性，不得私自将开发的相关信息泄漏出去，即使对家人或开发团队中的其他开发人员也不得泄漏。但开发人员有责任将开发的相关信息告诉项目的负责人员或开发小组的负责人员。以书面的方式将员工的权限和相应的责任提交给员工本人。必须严格规定在为企业工作期间，所有和工作相关的开发成果的所属权都归企业所有。应根据员工权限和责任的大小确认是否需要签署相关的保密协议。应在日常工作中记录员工与开发相关的日志信息。员工一旦离职或调动岗位应立即收回或调整其相应的权限。开发人员必须训练开发安全代码的能力在整个开发的过程中必须完整持续地进行代码错误处理所规定的流程。错误问题报告应力求通俗易懂，不应在其中包含任何系统细节问题。应对重要的敏感信息进行加密保护。应使用一些相对复杂的加密和密钥生成机制。应单独编写安全性设计说明概要分离系统开发和运作维护管理层必须确保应用系统的开发和运作管理从组织人事和权限职责上分开。
信息技术人员可以现场修复或更改偶然或恶意的数据和软件问题。测试代码中往往包含调试或者查错代码，大大增加了主机系统的性能负担。开发人员不应具有很高的权限，否则将在系统运行中产生很大的风险。
建立系统开发安全需求分析报告
安全需求计划应能够达到期望的安全水平。其中包括了成本的预估，完成各个安全相关流程所需的时间。所有关于应用系统的更新或改进都必须基于业务需求，并有业务事件支持。这里的业务需求不仅仅包括了系统的功能、性能、开发费用、开发周期等内容，应明确系统的安全要求。应用系统的任何一次改进或更新都应和该业务系统的所有者密切相关。开发安全需求分析计划应由开发项目经理和公司内部的安全小组共同商议决定。应确保每一个应用系统的用户都意识到系统的更新或改进都与其自身密切相关，所有的更新或改动建议都必须基于业务需求，而不是基于所谓的“信息技术的要求”。系统的每一次更新或改进都必须认真对待，必须进行详细的需求定义、需求分析以及测试评估，以保证不会对业务造成任何不良影响。业务需求是系统更新和改动的基础，因此必须清晰明确地定义业务的需求，禁止在业务需求未经业务部门领导和主要负责人员认可的情况下，盲目地进行开发工作。系统设计阶段的安全规范
单点访问控制且无后门
任何用户如果希望访问应用系统中的某一部分，则必须通过统一且唯一的认证授权方式及流程。
人员职责和权限的定义
由于不是所有的人员对于某一个应用系统都具有同样的访问或使用权限，因此系统必须具有基于人员职责的用户授权管理，以确保每个用户可以访问到其权限范围内的应用系统部分。同时应确保每个用户无法访问其权限范围以外的应用系统部分。
确保敏感系统的安全性
将应用系统中敏感的信息保存在服务器端以进行集中的加密的安全管理，确保客户端系统本身并不能存储任何敏感的数据。
确保访问层的安全性
应用系统不仅仅要确保系统模块本身的安全性，同时还应考虑模块与模块之间通讯的安全性。这种模块与模块之间通讯的安全性不仅仅包括了应用系统内部模块之间通讯的安全，也包括了应用系统内部模块和外部模块之间的通讯安全性，如主机和客户端之间通讯的安全性、服务器和服务器间通讯的安全性，以及本地系统和异地系统之间通讯的安全性。
确保日志管理机制健全
应建立可根据情况自由设置的日志管理机制，也就是说日志记录的范围和详细程度可以根据需求自行定制，且可以实现在应用系统的使用过程中进行日志的定制和记录。保留所有与系统开发相关的程序库的更新审核记录。
新系统的容量规划
容量规划是指确定系统的总体规模、性能和系统弹性。容量规划的具体内容可能有所不同，但一般应考虑以下方面：
系统的预期存储容量和在给定的周期中获取生成和存储的数据量。在线进程的数量和估计可能的占用资料系统和网络的响应时间和性能，即端对端系统系统弹性要求和设计使用率（峰值，槽值和平均值等）安全措施如加密解密数据对系统的影响。24x7运作要求和可接受的系统宕机次数（维护或者设备更新导致的必须性宕机）规划容量的时候关于系统使用的信息了解的越多越好。近来，由于互联网站的使用以指数形式增长，容量规划的变动效果不是非常显著，有时甚至毫无用处。原因在于很难估计实际的负载。在容量估计的时候应尽量将情况设想得复杂一些。
系统开发阶段安全规范
系统开发语言
程序员可使用很多指导规范来防止应用程序中的普通安全问题。其中许多可以应用于任何一种编程语言，但某些是针对特定的语言的。特定语言的指导规范主要集中在Perl，Java和C/C++语言。大多数情况下，一般的错误可以避免。而这些本可以避免的错误常常会导致很多安全漏洞，从而威胁信息的保密性、完整性和可用性。
通用规范输入验证在客户机/服务器环境下，进行服务端的验证而不是客户端的验证（例如基于Javascript的验证）。通过在客户端和服务器之间放置一个代理服务器，可以很容易绕过客户端验证。有了代理服务器，攻击者可以在数据被客户端“验证”后修改数据（与“man-in-the-middle”攻击类似）。
在实际的校验中，输入校验首先定义一个有效（可接受）的字符集，然后检查每个数据的字符是否在有效范围内。如果输入中包含无效的字符，应用程序应返回错误页面并说明输入中包含无效字符。这样进行验证的原因是定义无效的字符集比较困难，并且一些不应有效的字符通常不会被指出。
边界检查（例如字符串的最大长度）应在字符有效性检查以前进行。边界分析可以防止大多数缓冲区溢出漏洞。
从环境变量获得的数据也需要进行验证。同时避免在环境变量中存放敏感数据（例如密码）。某些Unix系统（例如FreeBSD）包含ps命令，可以让用户看到任何当前进程的环境变量，这常常会暴露保密性信息。
SQL语句如果应用程序需要连接后端数据库，不得在代码中使用SQL语句。使用程序以外的嵌入在代码中的SQL语句调用特别危险，难以防止攻击者使用输入域或者配置文件（由应用程序载入）来执行嵌入式的SQL攻击。而输入验证有助于缓解这种风险。
注释代码(commented code)当应用程序在实际环境中开始应用时，应删除所有的注释代码。注释代码是用来调试或者测试的，它们不是最终应用程序的一部分。无论如何应在实际的环境中删除它们来避免意外的执行（一般注释标识被删除后就无法激活休眠的代码，但还是存在可能性的，所以应执行这项工作）。
错误消息所有对用户显示的错误信息都不应暴露任何关于系统、网络或应用程序的敏感信息。如果可能的话，应使用包含编号的一般的错误信息，这种信息只有开发者和/或支持小组才能理解。一般的错误信息的例子是“发生了错误（代码1234），请您与系统维护部门联系。”
统一资源定位（URL）内容对于web应用，不要在URL上暴露任何重要信息，例如密码、服务器名称、IP地址或者文件系统路径（暴露了web服务器的目录结构）。这些信息可以在攻击时使用。例如下面就是一个不安全的URL：
设置PATH变量设置PATH为一个已知的值，而不仅仅是使用启动时的缺省值。攻击者可以在攻击应用程序时使用PATH变量，例如试图执行一个任意的程序。这些也可以应用于大多数其他的语言。
Perl语言多年以来，Perl已经成为用于系统管理和Web CGI开发的功能最强的编程语言之一（几乎可以使用Perl实现任何功能）。但其扩展应用，即作为Internet上CGI的开发工具，使得它经常成为web服务器上的攻击目标。另外，大多数CGI脚本有着比一般用户更高的权限，导致它更容易受攻击。下面列举了一些开发者（特别是CGI程序员）可以使用的主动的预防性的措施来增强Perl代码的整体安全性（请注意：这不是web服务器CGI脚本安全性的指导原则）。
Taint验证Perl版本5.x包含一个叫做Taint Checking的数据验证措施。如果起用该功能，它就不允许通过用户输入（任何程序外的输入）来操纵其他的外部程序（例如通过管道将数据导入另一个程序执行））。一般而言，程序员不能信任输入脚本和程序的数据（叫做Tainted数据），因为无法保证它不会产生危害（有意或者无意的）。Taint验证可以通过在命令行参数加入“-T”来开启。例如可以Perl脚本的第一行这样加入“-T”：
#!usr/bin/perl5 -T 
Tainted数据包括命令行参数、环境变量和来自文件的数据。引用tainted数据的变量也成为tainted数据。如果脚本试图通过不安全的方式来使用tainted数据会产生一个致命错误（对这种情况称为“不安全的依赖”(Insecure dependency)或者其他的说法）。启用tainted验证在有些情况下会导致脚本停止运行，常常是由于Perl解释器要求所有脚本引用的外部程序的完全路径必须在PATH环境变量中列出，同时PATH中包含的每个目录除了目录的所有者及相应的所有者用户组外无法修改。Taint验证对于环境比较敏感，这就可能会导致大多数程序员不愿使用它，但是只要可能就应使用taint验证，特别是代码执行其他程序功能时（例如在CGI脚本的情况下）。
安全模块如果不但输入数据不可信而且实际的代码也不可信会产生什么情况？例如用户从网站上下载了一个ActiveX控件，而它实际是一个特洛伊木马(Trojan horse)。这种情况下taint验证就不起作用。安全模块让程序员可以在Perl脚本中将不同的代码模块与安全对象相联系。每个安全对象对于运行的每块代码建立了一个限制的环境。这与chroot在一个进程中只能在整体目录结构的一个子目录中运行类似。而saft对象限制perl代码只能在perl包结构的某些特定包中运行。如何使用安全模式超出了本文的范围，但程序员应在任何时候使用这一功能。
警告参数(-w)使用-w参数可以在Perl解释脚本时显示所有的警告信息。警告可以对以下情况产生：只使用了一次的变量或者完全没有使用过的变量，未定义的文件句柄，未关闭的文件句柄，或将非数值变量传递到数据变量。该功能不是针对安全处理的，但是有助于调试直接或者间接对安全有危害的错误。一般推荐总是使用-w参数。可在taint验证时在第一行这样使用-w参数：
#!usr/bin/perl5 –Tw
Java语言自从1995年发布以来，Java成为简单或者复杂网络应用的有效编程语言。它在设计时充分考虑了安全问题，因此它具有的限制特征有：收集不再使用的内存碎片的垃圾收集器，严格的“sandbox”安全模型，以及在特定主机上限制应用程序的活动的安全管理器。以下为使用中的相关的规范：
不应在标准输出上打印消息在实际的Internet系统中避免使用System.out.println()或者System.err.println()打印日志和错误消息，原因是当消息打印到标准输出时，无法立即确定消息发生的地点，且有可能将敏感信息透露给攻击者。
封装Java中，如果没有使用访问标识符(access modifier(private、protected或public))来声明类、方法和属性，那么它的默认访问范围是包，并且同一包中的所有类都能访问它。必须记住虽然包有封装功能，但它只有在每部分加载到包的代码都由授权用户控制时才起作用。恶意的用户可以加入他们自己的类，从而对于包中的所有类、方法和属性都有完全的访问权限。Java的政策文件支持两种控制包访问权限的前缀。accessClassInPackage defineClassInPackage 所有标准库中的类都默认是可以公共访问的（除了由“sun”开头的类）。为了保证一个包的安全性，必须修改${JAVA HOME}/jre/lib/security文件夹中的java.security文件。该文件中的重要行是：package.access=sun.虽然该方法有作用，但仍存在问题。例如程序员在java.security文件中定义包的安全时必须十分小心。在package.access中的值是字符型的，“sun.”将保护“sun.tools”等包，但是不会对“sun”或者“sunshine”等包进行保护。另一个方法是使用JAR密封(sealing) 。JAR(Java ARchive)文件是一些类的打包压缩格式的文件，与常用的ZIP格式类似。如果从一个密封(sealing)的JAR文件中加载一个类，随后同一个包的类只能从该JAR文件加载。为了起用密封(sealing)，必须在建立JAR文件时这样设置密封(seal)参数：Sealed: true 使用密封(sealing)的JAR文件比权限 (permission) 设置更好，因为它不需要安装安全管理器(security manager)。政策文件Java内建的安全管理器是对应用程序进行限制的一个方便的工具。很多情况下需要编制一个定制的安全管理器，JDK1.2及以后的版本提供了描述设置的方法而不是实施它们。这是通过Java政策文件实现的。可以用政策文件以相对模块化的方式控制文件系统和网络的访问。例如可以限制应用程序只能修改名字是foo的文件。
宜使用Java政策文件和安全管理器而不是重新创建一个类或者系统来限制对主机和网络的访问。
C/C++语言C本质上是不安全的编程语言。例如如果不谨慎使用的话，其大多数标准的字符串库函数有可能被用来进行缓冲区攻击或者格式字符串攻击。但是，由于其灵活性、快速和相对容易掌握，它是一个广泛使用的编程语言。下面是针对开发安全的C语言程序的一些规范。
缓冲区溢出避免使用不执行边界检查的字符串函数，因为它们可能被用来进行缓冲区溢出攻击。下面是应避免使用的函数。同时，也列出了每个函数相应的比较安全的替换方式。
不使用strcpy()，使用strncpy()不使用strcat()，使用strncat()不使用sprintf()，使用snprintf()不使用gets()，使用fgets()在上面的前三个中函数中，每个替代函数的“n”表示了使用的缓冲区的大小。最后一个函数的“f”，表示格式，它允许用户指定期望的输入的格式。这些替换方程强制程序员定义使用的缓冲区的尺寸以及确定输入的类型。
格式化字符串攻击（Format String Attack）该类攻击往往与缓冲区溢出相关，因为它们往往主要利用了某些函数的假设，例如sprintf()和vsprintf()假设缓冲区的长度是无限的。然而即使使用snprintf()替换sprintf()也无法完全保护程序不受格式化字符串的攻击。这些攻击通过直接将格式说明符（format specifiers）(%d，%s，%n等)传递到输出函数接收缓冲区来进行。例如，以下的代码就是不安全的：
snprintf(buffer, sizeof(buffer), string) 
这种情况下，可以在字符串中插入格式说明符来操纵内存的栈，来写入攻击者的数据（这些数据中包含小的程序代码，并可由处理器接着执行）。 更多关于这些攻击的具体内容请见资源章节。对以上的例子建议使用下面的代码。
snprintf(buffer, sizeof(buffer), “%s”, string) 
进行格式字符串攻击不太容易。首先攻击者必须能获得内存栈的内容情况（从应用导出或者使用调试器），然后必须知道如何精确访问特定的内存空间来操纵栈中的变量。
执行外部程序推荐使用exec()函数而不是system()函数来执行外部程序。这是因为system()接收整个命令行的随机的缓冲区来执行程序。
snprintf(buffer, sizeof(buffer), "emacs %s", filename); 
system(buffer);
在以上的例子中，可以通过使用分号利用文件名变量在sehll中插入额外的命令（例如文件名可以是/etc/hosts; rm *，这将在显示/etc/hosts目录文件的同时，删除目录中的所有文件）。
而exec()函数只保证第一个参数被执行：
execl("usr/bin/emacs", "usr/bin/emacs", filename, NULL);
上面的例子保证文件名仅仅作为一个参数输入Emacs工具，同样它在Emacs命令中使用完全的路径而不是使用可以被攻击者利用的PATH环境变量。
竞争条件（race condition）进程需要访问资源时（无论是磁盘、内存或是文件）通常需要执行两个步骤：
首先测试资源是否空闲可用如果可用，就访问该资源，否则它等到资源不再使用为止再去访问它当另一个进程在步骤1和2之间想要访问同一个资源时将出现问题，导致不可预测的结果。进程可能会被锁定，或者一个进程籍此获得了另一个进程的较大的权限而导致安全问题。攻击主要集中在有较大权限的程序上（称为setuid程序）。竞争条件攻击通常利用程序执行时可以访问到的资源。另外权限低的程序也存在安全风险，因为攻击者可能会等待有较高权限的用户执行那个程序(例如root)，然后进行攻击。
下面的建议有助于缓解竞争条件(race condition)攻击：
在进行文件操作时，利用那些使用文件描述符的函数而不使用那些使用文件路径的函数（例如使用fdopen()而不要使用fopen()）。文件描述符使得恶意的用户在文件打开时或是在原始的进程对文件进行操作前，无法使用文件连接（符号式的或是物理的）来改变文件。
在写文件甚至在读文件时宜使用fcntl()和flock()函数来对文件加锁，这样它们就不能被其他进程访问。它几乎可以建立原子级的操作。
应谨慎操纵临时文件，因为它往往会导致竞争条件攻击。
检验有效的返回值检验有效的返回值非常重要。一个例子是旧的/bin/login的实现中不检验错误的返回值，导致当它找不到/etc/passwd文件时返回root的访问权限。如果该文件损坏了则这种情况是合理的；但如果该文件存在只是无法访问，那么这就是一个大问题。
系统开发安全相关工具管理
有许多方法来确保代码符合一定的安全级别。正如前面指出的，最好的方法之一是让尽可能多的人来检查代码（而不是在QA环境中实际进行白箱或者黑箱测试）。然而，有时代码在开始实际环境的应用前往往没有足够的时间，并且即使检查代码也会漏掉一些不易发现的错误。这些错误可能会对整个系统导致重大的安全问题。因此（以及其他的原因），使用源码分析工具(Source Code Analysis Tool(SCAT))来自动进行某些检查过程很有帮助。本文介绍了一些这方面的工具。每个工具都用同样的测试工具来检验，这些测试工具包含C和Java的代码段，而这些代码段存在潜在的安全错误。我们比较了每个工具的测试结果，并且仔细检查了以下的属性：
灵活性 － 有多种选项并能扫描多种类型的代码的工具得分会较高。正确性 － 主要目标是发现正确的安全问题，并且不会出现大量的误报信息，或者更糟的是没有发现真正的错误信息。容易使用 － 大多数情况下，程序员只需将工具指定到特定的代码上然后选择“扫描”。除非特别需要，程序员一般只做抽样检查，而无需开发复杂的测试机制。报表 － 扫描结果应以一种容易理解的格式来显示，并且最好同时提示修改每个问题的方法，并附加理由。每个工具在解析代码上的速度可以忽略不计，所以没有进行比较（虽然这并不包括配置扫描的时间，而MOPS在这方面相对于其它工具需要更多的时间）。另外，这些工具都可以免费获得，甚至可以获得它们的源代码，所以不需考虑它们的成本。工具一：PscanPscan是一个有针对性的扫描程序，主要用于发现C程序中的缓冲区溢出和格式化字符串攻击。该程序检查所有用到标准C程序库中的printf()函数。
sprintf(buffer, variable); 
printf(buffer, variable); 
关于这些语句在缓冲区溢出和格式化字符串攻击中怎样被利用可以查阅相关的C和C++文档。Pscan的一个不足是不能发现由于越界检查不充分而引起的常规性缓冲区溢出。但Pscan对于缓冲区溢出和格式化字符串攻击的定位还是相当精准和快速的。Pscan程序相对简单，它只将结果返回标准输出，当然也可以将其输出到文件，并且除了说明程序员应怎样修正错误以外，不给出语句为什么出错等类似信息。该工具一个显著的特点是可以同时扫描多个文件。
总体而言Pscan程序相对简单，易于使用，同时针对性很强，但是由于它能够适用的范围过于狭窄因此一般不推荐其在大型商业应用中使用，而只是检查一些相对简单的程序片断。
工具二：FlawfinderFlawfinder是一个分析C程序安全隐患的静态分析工具。和Pscan类似，该程序可以发现很多种类型的错误，除了printf()和标准的字符串函数，它还可以发现竞争条件和系统调用。Flawfinder相比较Pscan，它返回的错误信息要丰富很多，并且也更加详细。而这对于程序员来说非常重要。Flawfinder甚至可以对程序中的弱点进行分类，例如buffer弱点、格式弱点、shell弱点等。 
Flawofinder是一个相当出色的C程序检查工具，速度会，界面友好，返回信息丰富，安装使用相对简单。该工具是检查不同规模的应用程序的首选，唯一不足的是它只能用于C程序的检查。
控制软件代码程序库
管理运作程序库我们通常将用于系统开发的软件工具和开发平台称之为运作程序，因此为了降低计算机程序被破坏的可能性，应对运作程序库的访问进行严格的控制：
严格的管理在开发设备上的存放开发运作程序的目录。如果开发运作程序没有很好的保护，则系统及其设置可能遭到未经授权的访问，并造成系统的安全性可靠性大大下降。只有指定的人员如程序库管理员经过适当的管理授权后，才可以访问运作程序库，对运作程序库的访问必须结合严格的访问控制技术手段和双重访问控制机制。严格的访问控制可以通过以下规定实现严格管理开发部门所在区域的保安管理，防止未经授权的人进入开发区域。严格管理开发用途的计算机使用，只有指定的人员才可以访问开发用的计算机设备。严格管理开发运作系统的认证管理，建立严格的基于人员职责的授权等级制度，用口令或其它身份识别技术确认访问者身份。建立双重访问控制机制双重访问控制机制就是对运作程序库的管理需经两个人同时进行认证后才可通过的方式。比如对运作程序库进行更改或删除需要两个人进行口令认证，系统才允许进行以上操作。需要进行认证的两个人彼此不知道对方的认证口令或步骤。因此该认证过程必须两个人同时在场才可进行操作。
管理源程序库源程序包含了系统及其控制如何实现的细节，为修改系统提供了很好的切入点，例如设置逻辑炸弹。且如果缺少源程序代码会使得今后应用系统的维护工作十分困难甚至无法完成。因此为了降低计算机程序被破坏的可能性，应对源程序库的访问进行严格的控制：
严格管理在开发设备上的存放源程序的目录。如果源程序没有很好的保护，则系统及其设置可能会遭到未经授权的访问，并造成系统的安全性可靠性大大下降。只有指定的人员如程序库管理员经过适当的管理授权后才可以访问源程序库，对源程序库的访问必须结合进行严格的访问控制技术手段和双重访问控制机制。各项应用均应指定相应的管理员。信息技术支持人员(非开发人员)不应自由访问源程序库。源程序库和运作程序库宜分开存放并且分开管理。源程序库和运行的应用系统宜分开存放且分开管理。源程序库的更新和向程序员发布的源程序应由指定的管理员根据一定的授权进行，不得私自进行更新或发放。应保存所有对源程序库进行访问读取或修改的日志记录，以便日后审核。
在软件开发过程变更管理
a)系统容易受到未经授权的变更的影响，即使是完全授权的更改也可能存在破坏性的影响，存在数据完整性的损失、应用系统的不可用以及机密信息的泄漏的风险。为了使信息系统的损失降至最小，组织应对更改进行严格的控制，即在系统开发的每一个阶段（可行性研究、需求分析、设计、编码、测试、培训等）的每一个更改实施前必须经过组织的评审与授权。
b)对于敏感的应用系统的更改应由另一人员进行检查，为了有效的进行控制，组织应建立更改控制审批程序，对更改的申请、评审、测试、批准、更改的计划的提出和实施提出明确要求并严格的实施，确保安全性与控制程序不被损害，程序设计人员应只能访问他们工作所必需的部分，确保任何的改动都应经过审批的。
c)更改的程序宜如下：
清晰确认所有需要更改的应用系统、信息、数据库和相关的硬件设备。清晰确认更改的原因(业务上的具体流程和具体的需求或开发上的需求)。由授权的用户提交更改申请。保留相关的授权登记记录。在正式实施之前，更改的方案必须经过评审并通过正式的批准。确保授权的用户在实施之前确认并接受更改的内容。确保在实施的过程中，尽量减少对现行的业务运作系统的影响。确保建立的文件系统在完成各项更改时得到修改，旧文件被很好的归档或处置。保证所有的应用系统升级的版本控制。确保对所有的更改请求进行审核跟踪。确保用户使用手册作相应的必要的更改。确保更改的实施选择了适当的时机，以确保更改的实施不会干扰正常的业务运作。
开发版本管理
控制程序清单源程序相关信息可以帮助确认系统问题的根源，并且一旦掌握了系统源程序相关信息可以清楚地了解系统的运行逻辑和可能的薄弱点，对系统的安全有很大的影响。
在任何时候对于程序清单必须进行严格的控制并且及时地进行更新。对应用系统开发源程序的打印资料、电子版本或者是相关的报告都必须进行控制，纸质的文件应保存在一个安全的环境下，如保险柜等。电子文档则应进行一定的加密。版本升级控制应用系统软件开发版本升级申请。当软件的版本由于更新、修改等操作需要升级时必须先向相关负责人员提交申请。应用系统软件版本升级测试。对升级的应用系统进行测试，确认系统的各种安全特性。应用系统软件版本审批。对应用系统的版本的升级，应确认当前的版本为最新的版本，旧的版本应进行归档，不得随意丢弃或删除。应用系统软件版本升级计划。制定相关的升级计划，确保将系统升级对业务的影响降至最低。应用系统软件版本升级实施。版本变更控制版本变更应提出申请，详见4.4“软件开发过程变更管理规范”。应使用软件加锁技术防止不同版本相互覆盖的情况。当版本变更时应在更新的版本中记录变更的详细描述。应提供版本的合并功能。版本的更改应只允许指定的人员进行操作。应记录所有的版本变更的日志，其中包括更改日期、更改前版本号、更改后版本号、更改人、审批人等信息。
开发日志审核管理
开发日志定期审计系统开发中的相关日志文件应根据开发周期定期审核。
开发人员权限定期审计开发人员权限定期（3个月）审核一次。
防御后门代码或隐藏通道
后门代码和隐藏通道介绍a)后门代码，主要指由攻击者在未经许可的情况下，植入计算机系统的程序。利用调用环境的权利进行与其实际用途无关的拷贝、滥用或破坏数据，主要有三种类型的后门程序：
调试后门——为了方便调试而设置的机关，系统调试后未能及时消除。维护后门——为了方便远程维护所设置的后门，被黑客恶意利用。恶意后门——由设计者故意设置的机关，用来监视用户的秘密甚至与破坏应用系统。特洛伊木马也属于后门的一种，它是黑客攻击计算机的重要手段之一。特洛伊木马可以放置在正常的文件或程序中，当用户打开或执行它的时候，它就会自动安装在计算机上，使得某些人通过Internet访问该计算机成为可能，使计算机处于一种非常危险的状态。b)隐藏通道，主要指在计算机安全技术中，一种允许某个进程在违反安全规则的状态下传递信息的通道。隐藏通道可以通过某些直接的或间接的方法暴露信息。现在使用的应用系统中大多数都包含一定程度的隐藏通道，他们当中许多是无害的，像特殊的组合健可以给出软件制作者的信息，但也有些是有害的，因此必须进行相应的防范。
防御后门代码和隐藏通道的相关办法应从信誉好的软件供应商那里购买相关的软件或程序。应检验和验证源程序和源代码。在系统正式投入使用之前应进行评估，如一些行业的标准认证评估(产品安全认证、CMM认证等)。在系统正式投入使用后，应严格管理源代码的访问、升级和修改。应使用可靠的开发人员操作密钥系统。不应随便从一些不知名的网站上下载软件。不应过于相信别人，不得随便安装别人给的软件，特别是不得随便打开电子邮件中的附件，一些可执行文件必须先进行病毒及恶意代码的扫描。安装并正确地使用有关的特洛伊木马的监测和查杀程序，现在大多数主流的杀病毒软件也带有该功能，目前比较流行的专门用于查杀特洛伊木马的程序主要有Lockdown2000、The Cleaner、Trojian Defence Suit等。系统测试阶段安全规范
应用系统的安全性检测
设计详细的测试计划、测试范围、测试方法和测试工具对软硬件的测试必须事先有正式的测试计划。测试计划的一个关键点是测试计划文档不仅要包含测试的内容同时还需要包含测试预期的结果。并且测试计划还需要覆盖除此之外的测试内容和结果，使之更加全面。测试完成以后，需要对测试结果进行评估，确定其结果是否达到了预定的标准。如果达不到标准，则应对测试结果划分一个错误严重性等级，否则无法对结果进行客观评论。
测试种类测试的过程需要用户的参与以确保系统达到了业务上的需求和用户使用的需求。因此主要分为系统测试和用户接受测试。
系统测试系统测试有很多种定义。一般而言系统测试可以定义为：在人工环境下，测试系统是否能够达到预期的要求的测试方法。
从系统开发的角度而言，系统测试是指由系统开发人员（程序员和其它技术人员）进行的，旨在确保系统各个模块能够正常运行（模块测试）以及系统整体能够正常运行的测试过程。系统测试必须确保系统的每一个功能都能够正确运行，并对所有的程序错误逐一分析。同时还测试系统的模块和模块之间、功能和功能之间的接口的正确性。需要注意的是系统测试不对系统总体的功能负责，而只需要达到测试计划中规定的测试准则即可。
a)系统负载测试，负载表示对系统的要求，一般包括以下因素：
程序和数据的总体存储容量并发运行的应用程序数量并发用户的数量，峰值，槽值和平均值外设数量确定硬件的规模比较复杂，在确定了上述因素以后，还应确定其它类似响应时间等因素。b)压力测试
压力测试用于确定系统的薄弱环节，确定系统在非正常条件下能够迅速恢复到正常的运行状态的能力，类似的非正常条件可能是在系统宕机、网络故障或者高峰载荷下的数据处理等。
用户接受测试－UAT用户接受测试是用户对新系统或者系统改动正式验收测试的过程，是任何系统开发项目都需要经历的重要阶段，并且需要终端用户的大力参与。在现实中，UAT需要有周密详尽和准确的测试计划，特别是验收的标准必须非常详细。UAT的最后部分往往包括并行运行，以比较开放系统和原有系统。
a)尽管系统的用户接受测试计划可能随着系统的不同而不同，测试必须涵盖所有今后实际运行中可能发生的事件。测试计划一般可以在系统开发前制定的用户需求说明书的基础上制订。
b)对任何系统而言，对于出现的问题必须要明确要对这些问题做出哪些应对措施以及谁来做这些应对措施，例如用户、项目团队、供应商或者是咨询顾问等所有可能的项目参与方。
c)为了更好地应对测试过程中可能出现问题，最终用户和项目团队必须协商制定“错误严重程度”的范围。它的取值范围从1到6，分别表示从业务/商业影响角度评估在系统测试过程中发现问题。下文是一个成功应用的例子，“1”表示最严重的错误，而6则表示最轻微的影响。
“致命问题”——如果该程度错误发生，则测试不能继续。“重大问题”——测试可以继续，但是系统不能上线。“主要问题”——测试可以继续，但是如果不解决该问题，则系统上线后，可能对业务流程有严重破坏。“一般性问题”——除了这些问题会对既定的业务流程有一些轻微偏离外，测试可以继续，并且系统也可以上线。“次要问题”——可以继续测试和上线，但这些问题必须修正，同时这些问题对业务流程没有或者很少有影响。“粉饰性问题”——类似颜色，字体等问题，如果这些问题对于业务需求而言特别重要，则需要将这些问题提高到较高层次。系统的用户在征得主管项目的高层领导意见的前提下，必须就每类错误需要采取的行动和各自需要承担的责任等问题取得一致。例如，可以要求马上解决严重程度为1的问题，并停止所有测试计划直到该层次的问题解决。注意事项：为避免类似分级问题的风险，在测试规划中宜给出每一类问题的例子，以避免对问题分级出现根本性的不一致。当有不一致的时候应预先的准备。d)最终用户和系统开发上必须就每一类错误的数量有一个上限。
注意：有些情况下用户可能会有条件接受。这些条件可能增加了工作范围。在这种情况下以及所有对系统的修正都需要非常严格的用户接受测试和必要的回归测试。
在测试的过程中详细描述每个和测试方案相关的测试步骤和测试数据将所有的测试数据进行整理归档，将出错的记录进行分析，确认问题产生的原因并编写问题报告。
控制测试环境
控制系统测试环境和实际工作环境应隔离的进行控制处理，否则
未经确认的软件修改会导致出现无法预料的问题。工作人员在两个环境里切换，容易操作失误，引起不必要的麻烦。开发与系统测试同时进行容易导致对系统状态的错误估计。
为测试使用真实的数据
测试的数据通常情况下是虚构的，但是有时候需要使用实际的操作或运作的数据，当该数据含有企业敏感信息的时候，如果不加以控制，会造成数据的泄漏。当处于测试目的而使用真实的敏感的数据时，可以采用以下措施保护测试数据的安全：
对测试的系统进行严格的访问控制。只允许小部分的测试人员进行测试。且测试的人员应签订安全保密协议。每一次将真实的运作信息复制到测试系统时均需要一个单独的授权过程。测试完成后，应立即将相关数据从测试的应用系统中删除。记录下测试数据的复制、使用和删除的情况，以便于审查追踪。
在软件转移至生产环境前进行测试
在软件程序上线投入使用之前，必须采取切实的措施保证这些软件接受了足够的测试和记录。否则就有可能导致非常严重的问题，甚至导致企业的日常运营中止。必须牢固树立类似的观点。
应用系统安全质量鉴定
目前国际上公认的开发质量验证标准主要有两种，可以根据这两种标准确认系统是否已经达到了这两种标准的要求：
ISO 9000认证体系软件开发能力成熟度模型(CMMI)系统培训及文档阶段安全规范
新系统的培训
对所有的用户和技术人员提供关于新系统功能和操作方面的培训。必须保证所有的技术和业务用户接受足够的关于新系统或者系统改进的培训。培训应有侧重，而[1]不是面面俱到、人人俱到关于应用系统的安全性方面的培训应摆在十分重要的位置。
撰写新系统和系统改进的文档
如果缺乏足够的文档，当系统发生问题的时候，只能凭经验解决，而有可能会错上加错。同样文档的不完整，不及时更新也会对系统的维护能力造成致命的影响。
所有新系统和系统改进都必须有充分的最新的文档支持，如果文档没有具备则系统不能上线。必须保证新系统和系统改进有详实的文档。不可由于资源和预算的限制，而导致文档不充分或者完全没有是不允许发生的事情。应用系统开发外包安全控制[1]
如果对于外包(Outsourcing)应用系统开发过程缺乏有效的安全控制，组织就会面临很多的风险，例如应用系统本身的质量问题、应用系统本身隐藏了特洛伊木马或隐藏通道等。因此组织必须对开发外包进行一定的管理确保外包的安全，建议采取以下的控制措施：
应选择一个信誉与质量保证能力卓著的软件开发商来为自己开发软件。例如开发商应通过了ISO9001质量管理体系认证或软件成熟度CMM等级。应与外包的供应商签订商务或技术合同或协议，明确软件的质量、知识产权与安全要求，以及软件本身的安全功能与开发过程的安全控制要求。应与外包的供应商确定软件开发后的使用许可、代码的所有权和相关知识产权的归属问题。开放商应出具所开发的应用系统的质量证明和完成工作的精确性。应在系统正式投入使用之前仔细测试代码中是否包含了特洛伊木马程序或隐藏通道。