安全模糊性不会让你的代码更安全

ZDNet软件频道 时间:2002-06-06 作者:BUILDER.COM |  我要评论()
本文关键词:SECURITY
本文我们将对模糊的(不透明的)安全性问题进行讨论,同时还要牵扯到涉及这一话题的某些争论。然后我们将讨论如何在严格开发实践中防止系统和数据落入黑手。

回想1984年的时候,技术人员Stuart Brand曾经说:“世上没人愿意为信息掏腰包。”作为一名程序员,谁来保护系统所创造和利用的信息呢?谁来保证信息的连续性和适当的访问权限呢?责任只能在你了。采用遮遮掩掩的安全策略和设计真的不会让人注意到以上的问题吗?不,这样做的结果只能是错误地忽略了这些责任。这无异于向非法攻击者公开发出邀请信!其实,你只要付出点额外的努力就能够阻止代码中出现严重的安全漏洞。

下面我们将对模糊的(不透明的)安全性问题进行讨论,同时还要牵扯到涉及这一话题的某些争论。然后我们将讨论如何在严格开发实践中防止系统和数据落入黑手。

从安全的广义含义来看,世界上没有任何应用程序敢说自己是绝对安全的。原因何在呢?其实,不管是哪种主流的平台和安全概念,从技术上说,只要给定足够的时间和处理就肯定能被破解。

“安全的模糊性”意味着用户或者外部世界完全不知道你特定的体系结构。虽然你无法保证自己的系统永远不会受到安全方面的损害,不过,只要你的程序编码规范、正确就必定能有助于保证自己的应用程序不会轻易在任何解密高手或黑客面前大门洞开。

摘下你的有色眼镜

读这篇文章可能吓着你了,没那么严重,有的时候,某些形式的安全模糊性反而对系统的安全性大有裨益。实际上,几乎每家公司都利用了“安全模糊性”防护其数据安全。举两个例子:其一是128位加密技术,这种加密技术依赖于算法和秘钥的隐藏;其二是网络地址解析(NAT),它隐藏了网络的内部体系结构。

那么反过来又会出现什么大问题呢?以前56位的加密算法对系统的安全来说已经绰绰有余,然后很快就有人证明这种加密级别可以被破解。采用非标准的系统端口一度被当作一种隐蔽服务的有效方式,但到如今,技术上再不济的用户,只要略知一二就能轻松下载端口嗅探器。我的看法是这样的,虽然以上这些措施在某些情况下可以提供一定的安全性,但不可避免的是,总有人会跑过来拉开隐藏内幕的窗帘,迫使我们改变自己的安全标准。

照我看,“伪安全”的真正问题在于,这一概念并不能约束产品为自身的代码增加额外的安全层。最大的危险还在于应用程序代码本身。用不着动用成千上万的人来为你找出程序中的缓冲溢出漏洞—一个黑客足矣!而他们总是特别喜欢非法获取别人的资源。

这些简单的事实搅得软件供应商和开发团体寝食不安,为了解决以上的问题,最终产生了2种不同的解决思路。

争论的发端

争论中的一方是腰缠万贯、开发专有软件的跨国软件公司领导人。另一方则是遍及世界各地、各自努力的开放源代码产业先锋。IETF在争论中起调停者的作用,它为解决这一问题而在2002年2月公布了一份适当暴露软件漏洞的Internet草案。

显然,模糊的安全性对专有软件供应商来说是合乎需要的。如果没人知道软件中所存在的问题,看来也就没人能利用到它们。客户自然也不必紧张;股票价格也不会下跌;企业的形象也能得以维护。这些公司把API源代码和其他技术产品信息揣得紧紧的,希望系统构架的隐晦能实现某种防止暴光的保护。

然而,这种做法的缺点,也是显而易见的:只要发现了一个恶意的漏洞,居心叵测的发现者就可以利用这个漏洞。如果软件供应商没有及时把问题通知给它的客户,显然后者也就多半没有采取相应的防范措施,从而令系统在即将到来的寒风中颤抖。

另一方面,开放源代码软件开发者则宣称,如果人人都能获得程序的源代码,那么,由于软件的问题能在被利用之前就被发现并得以解决,系统的安全性显然会大大提高。在结构性的模糊性所不存在的情况下,开发者们更可能采取真正有效的安全措施。

当然,开放源代码模式也有自身的缺点,尽管其源代码人人可用,但模糊性也是存在的。只要产品被发布,其源代码就可以免费使用,这显然是版本控制领域的一场恶梦。如果最初的源代码有危险,那么其他由其衍生的无数产品也可能会继承这些危险。为原始代码发布的程序补丁都可能不再适用或者无法与派生代码兼容。再者,仅仅因为最终产品用户量少、有一定的安全模糊性也并不意味着存有恶意的人就找不出产品所存在的问题。

你再怎么想办法软件安全都是一个相当头痛的问题。最好而且也是唯一能保证产品不轻易受到危害的方式就编写优良、明晰、考虑周全的程序代码。

自己动手

编写安全的代码并不总是给你带来负担。如果你仅仅接纳和包含了现有的编程实践,那么在你认识它们之前这些实践就已经过时了。我了解了一下对不安全软件的一些主要批评以及病毒主要的攻击领域,最后总结了如下所示的编程实践原则。

不要做:

  • 不要依靠其他的系统来保护你的代码,例如运行时环境和Web服务器等。你应该总是在自己的程序中创建安全机制。
  •         不要直接通过POST、GET或者其他用户输入变量执行系统调用或数据库查询。
  • 不要因为测试目的而在你的用户表中保存超级用户帐号。
  • 不要创建隐蔽的访问点(后门)供你采取非正常方式访问系统。如果你能这样做其他人也能。
  • 不要让你的应用程序获得root(又名超级用户、上帝等等)系统访问权限,最好为你的应用软件创建特定的用户并限制其权限。
  • 不许文件上载到你的主服务器。如果你非要这样做也得保证你创建了不能访问主要文件系统的分区或沙盒环境,而且系统上还必须运行着反病毒软件。
  • 不要在函数中采用广播协议,除非你能对信息有所限制或者对其进行了加密。
  •         不要给黑客留下任何攻击系统的机会,甚至包括应用程序中的错误处理和日志。例如采取下面的编程逻辑:if ( 出现这种情况 ){ 这么做;} else { 什么也不许做;}


要做的:

  • 限制应用程序及其功能的范围。永远不要设置你不打算使用的变量,懒惰的习惯往往会给某人带来访问关键信息的机会。例如,假设你并不需要field3,那么:“select  field1 , field2 , field4 from table ;”就比下面的语句要好些:“select * from table;”。
  • 检查用户输入信息中存在的错误,保证这些信息采用了适当的数据类型,同时限制可接受的字符。例如:如果你需要用户输入其姓名,则输入字符串只能由字母表中的字母组成,而不能采用%、^、$、&等符号。
  • 应用程序应该模块化,同时限制这些模块的访问权限。例如:如果你有个模块负责处理所有的数据库查询操作,那么只有具特定IP地址的服务器上的数据解析模块才能调用数据查询模块。
  • 用不同的模块分别(参考上一条)创建套接字和派生进程。
  • 为了准确起见,给那些交叉引用的所有数据分配秘钥。这样做的目的是防止用户A访问用户B的信息。
  • 不要设置或者干脆删除空变量。
  • 限制缓冲区和字段的大小。如果字段限制为50个字符,则在数据库、变量等所有场合都尽量实施这一限制。
  • 保证你已经禁用了闲置的功能,而且系统上的所有用户都拥有口令。
  • 经常留心安全讨论区,比如Cert或者eEye Digital SECURITY等。

采用以上这些指导性意见相信你不会给黑客留下太多的机会。这样你才是真正在实现安全的系统而非把一切都遮掩起来——那简直就是把头埋在沙地里的鸵鸟之举。

责任编辑:炒饭

欢迎评论或投稿


百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134