2012-07-19 15:10:15 来源:TechTarget中国
开发团队的所有成员应当清楚常见的编程错误及原因和减少错误的方法,以及这些内容对当前软件项目的适用性。减少软件项目安全漏洞的关键在于开发团队必须遵循安全编码的最佳方法。
验证输入并对输入进行编码
攻击者常常针对应用程序发动劫持攻击。这种攻击可以采用C语言中的格式字符串的形式,或者采用Web脚本语言中的跨站脚本攻击。如果一个Web应用程序可以接收用户输入,并将用户输入的内容输出或转发给某个可信的功能,它就易于遭受攻击。因而,正确地验证输入以确保它满足应用程序的要求(例如,通过验证用户的输入达到某个长度并且不包含“特定的”HTML字符,并且可以安全地处理任何非法的输入。)如果输入验证允许潜在的恶意字符(例如,在Web应用程序中出现“<”),后果就不容乐观。此时,应用程序就应当对这些字符编码,使其不会被其它功能或依赖它的应用程序误解。
白名单是很受欢迎的输入验证方法,它可以验证那些遵循了确定的可接受参数的输入并拒绝不遵循这些参数的输入。白名单验证已被证明可以高效地过滤与未知攻击有关的输入模式。相比较而言,黑名单这种方法可以验证输入是否与某些确定的与可疑恶意输入有关的不可接受的参数相匹配。黑名单可以接受并未明确标识为“恶意”的所有输入,它在防护未知攻击方面没有什么用处。但它可以清理某些恶意的输入。此外,黑名单还可用来临时过滤与零日漏洞的有关攻击。如果要使用黑名单功能,IT能够将输入转换为标准形式非常重要。IT应当结合使用白名单和黑名单,但应首先用黑名单。
在检测到恶意的输入后,就需要对其管理。最好的方法是简单地拒绝恶意输入,而不是试图“净化”它。然而,净化有时是必要的。在这种情况下,所有被净化的数据都应当被重新发送,以便于用白名单验证确保其有效性。
测试情形应当包括合法数据和非法数据的提交两个方面,而测试者应当重视似是而非(输入验证拒绝了合法输入)和“似非而是”(输入验证接受了非法输入)。如果客户端验证是作为第一层过滤而实施的,还应当测试其JavaScript情况(JavaScript在解析普通的表达式时与服务器的验证引擎略有不同,而且会在客户端生成似是而非的问题,并在服务器端产生“似非而是”的问题)。最后,测试者应当在关闭服务器端和客户端验证的情况下运行应用程序。这样做会揭示接受非法数据如何影响其它应用程序层,并会暴露漏洞。在对输入验证实施了集中化的架构中,测试还可以揭示是否在系统的其它点上需要其它的验证。必须确保验证不能被绕过。在客户端/服务器的设计中,服务器的验证是保护服务器的唯一验证。
标准化
在表达式遵循标准格式时,它就是标准化的。标准化就是对一个表达式进行重新格式化使其满足标准格式。标准化可以确保表达式能够被转化为标准格式。在验证之前对表达式进行标准化可以减少绕过过滤器的风险。
本地化
本地化包括为使一个程序在不同国家使用而创建的程序变种。开发者应当为软件的每一个本地化变种开发误用/滥用的实例和攻击模式。由于某些语言中的源字符串的长度更长,在不同字符编码中字符串长度可用字节或字符来表达,以及由于从一种编码转换到另外一种编码会导致缓冲区大小的增加,所以,与本地程序变种相关的主要问题都与产生缓冲区漏洞的可能性有关。
分析器
开发团队应当使用分析器来管理编码和转换等方面。现在有许多编码方案,如十六进制编码、Unicode编码、URL编码、基于语言的字符编码等。这里存在许多困难,其中之一就是这些编码可以通过双重编码的形式一起使用,从而使得标准化过程变得很困难。应用程序中内置的一系列分析器,如Web服务器和应用程序服务器可以减少这种困难。剩下的就是输入验证问题了,如果这是一种基于模式的验证方法,在分析器将输入变成标准形式之后才进行检查就至关重要了。这可能是一个架构上的挑战,并需要谨慎管理。
对输出进行过滤和净化
开发团队应当检查传递到外部实体(包括用户、支持库、支持应用程序)的输出,以保证它与允许输出的参数保持一致,并确保此输出仅包含所允许的内容。实质上,在将输出发送给外部的目标接收者之前,用于验证输入的同类检查也适用于输出,这些输出包括输出到屏幕、输出到其它系统等。在调用SQL数据库时,开发者应当使用能够自动去掉字符的模板调用。
一个简单的例子就是检查用户是否合法的功能。如果开发者仅希望从数据库的查询中返回一条记录,就应当检查是否返回了特定记录。只需检查一下,看看该功能是否返回了表明失败的多条记录。与此类似,如果一个数据库的查询要返回一条记录或少量记录,就可以通过输出验证来阻止返回超过特定数量的记录,从而可以防止由于应用程序错误或漏洞被利用而造成的数据泛滥。[page]
使状态信息的保留最小化
软件应当只保留最少的所需状态的信息,并且应当经常清除写到高速缓存中的数据和磁盘临时文件中的数据。如果软件发生故障,这些措施可以使敏感信息(其中包括可能被攻击者利用的软件自身的信息)被意外泄露的可能性达到最小。
不过,有时应用程序的数据必须保留状态信息,如cookies或会话数据。在这种情况下,程序员应当清楚攻击者可能访问哪些位置,不管是内存位置还是文件系统中的位置。状态数据和临时文件只能放在攻击者或程序之外的其它对象无法访问的地方。应当给临时文件起一个攻击者难以猜测的名字。此外,在程序终止执行时,还应当清除高速缓存中的数据,而且还要删除或覆盖临时文件。
不允许未经授权的特权提升
程序员不应当编写可以使用户或过程执行特权提升的逻辑。攻击者会监视这样一个进程:它试图引用另一个进程A,而进程A拥有比其自身更高的特权。攻击者将会解释这种由软件系统指示的特权提升和授权验证活动。开发人员应当使拥有更高特权的进程对攻击者不可见。如果攻击者看到了有更高特权的进程,就会利用它来提升其自己的特权。
合并进程间的身份验证
进程间身份验证的主要目的是将用户的身份和特权与用户所操作的应用程序的进程身份和特权联系起来。这样做可以使软件系统能够根据用户(人员的或软件实体的)与安全相关的特性来做出决策,例如,是否授权某实体访问某些数据或资源。进程间身份验证还可以使系统将软件的进程活动与其用户的经授权的身份连接起来。
但是,新的计算模式要求进程能够自主地动态激发其它自主软件的进程或代理。进而,这些代理可以动态地但更自主地激发进程或代理,所有这些代理都有可能在软件密集型的系统中被广泛地发布,甚至这些代理会属于其它的软件系统。
充分利用攻击模式
程序员可以使用攻击模式来确认相关攻击所针对的特定编码缺陷,并确保这些缺陷不会出现在其代码中。首先,程序员在考虑软件的架构和执行环境后,需要决定哪些攻击模式可行,哪些技术可用于实施攻击该软件。例如,对于一个运行在本地Linux上的C或C++程序而言,缓冲区溢出攻击模式就具备相关性,而对于一个运行在。NET平台上的C#程序而言,缓冲区溢出攻击模式就与之无关。根据需要避免的攻击模式,程序员应当决定哪些构造不应当出现在其代码中。
下面的例子展示了程序员如何利用攻击模式:
攻击模式:简单的脚本注入
用于:避免跨站脚本漏洞
此模式有可能针对的代码部分:即将输出的数据发送到一个来自不可信源的用户的代码部分。
如何保护代码避免遭受攻击模式:如果没有提前采取相应的反制措施(即,根据架构师的决策,在服务器和客户端之间的联结处,包括一个自包含的输入验证器/输出过滤器),就应当实施类似于下面的反制措施:[page]
1、将潜在的危险字符转换成其HTML的对等物,以防止客户端显示有可能包含非法数据或臆造数据的不可信输出,如由攻击者插入的<script>标签。这种转换的例子包括“<”变成“<”,或者“>”变成“>”;自动执行这种转换的第三方Java库;JavaScript的escape()函数也可以执行类似的转换。注意,需要谨慎管理这种转换,以避免由更长的字符串替换单个字符成造成的潜在的缓冲区溢出漏洞。
2、实施一种输入验证过滤器,使其可以根据允许输入的字符白名单对输入进行过滤。
实施加密和哈希
程序员需要加密敏感数据(例如,密码和会话ID),尤其是在不受信任的渠道(如互联网)更要如此。无法保护敏感数据可能会导致攻击(例如,会话劫持和跨站脚本攻击),导致对应用程序和数据的未授权访问。
加密功能在许多软件中是一种重要的工具,这会确保保密性和完整性。有许多程序可以创建自己的加密功能,如果程序被破解,就会使软件不安全。对程序员来说,没有任何理由和借口允许加密功能发生故障,因为所有的主流语言都有其安全的、经审核的加密函数库。使用这些库比用户自己开发这些功能要简单得多。下面是关于算法的一些建议:
对Web应用程序使用传输层安全(TLS);
不使用MD5和安全哈希算法(SHA-1),而应当使用SHA-256/512 and SHA-3哈希;
不要使用DES(数据加密标准),而应使用AES(高级加密标准)或Triple DES;
程序员所开发的程序还应当允许在算法被破解时,能够轻易地切换到另一种哈希和加密算法。
在部署之前禁用调试工具
核心转储仅能够在测试期间才可作为一种诊断工具使用。应当在部署应用程序之前对应用程序进行配置,在应用程序的实际使用期间如果发生故障,能够关闭其生成核心转储的能力。在程序发生故障时,不能使用核心转储功能,而应该在程序退出之前,由“例外事件处理程序”来将适当的数据发送到安全日志中。此外,如果有可能,应当将核心文件的大小配置为零(0)(例如,在UNIX中使用setrlimit或ulimit);这样做可以进一步防止生成核心文件。
显然,上述所谓的九大最佳方法,并非程序员编制健壮软件的灵丹妙药,但是只要其遵循这些方法,就可以极大减少程序遭受攻击或数据泄露的可能性。
免责声明:本网站(http://www.ciotimes.com/)内容主要来自原创、合作媒体供稿和第三方投稿,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证有关资料的准确性及可靠性,读者在使用前请进一步核实,并对任何自主决定的行为负责。本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。