第十二章 不安全感综合症——编写安全的程序

  • 大多数的软件系统都是需要一定的安全水平,无论软件系统处理的是否是敏感数据。
  • 要了解你拥有哪些重要的资源,你是否拥有攻击者可能会希望得到的非常敏感的信息或特定的能力。

    为什么会有人攻击你的系统呢?因为你拥有他们想要的东西,包括:

  • 你的处理能力。
  • 你发送数据的能力。
  • 你存储的私人信息。
  • 你的权限。
  • 你对更令他们感兴趣的远程系统的连接。

  • 只要存在一个不安全的程序,就会让整个计算机系统变得不安全。

  • 要保证系统的安全性,需要在管理制度上进行约束,这和编写安全的代码一样重要。
  • 计算机系统越复杂,就越有可能包含安全漏洞,因此,尽可能编写最简单的软件。
  • 不要对漏洞置之不理,并妄想自己是无懈可击的。
  • 我们必须做到知识更丰富、装备更好、对攻击方式更了解,并且更注意我们编写代码的方式,我们必须在一开始就为安全性而设计,并将它们放在我们的开发过程和计划中。

    软件系统中的缺陷主要包括:

  • 不安全的设计和体系结构。这是最基本的一种缺陷,也是最难已改正的一种。
  • 缓冲溢出。当缓冲器位于堆栈上时,溢出最容易被利用。
  • 嵌入的查询字符串。这种攻击可以用来使程序崩溃、执行任意代码,或搜寻未经授权的数据,也就是我们经常见到的SQL注入。
  • 竞争状况。依赖于事件执行顺序的系统有可能会被利用,以实现非预期的行为或使代码崩溃,这通常出现在具有复杂线程模型中或者由许多协作的进程组成的系统。
  • 整数溢出。如果在使用数学结构时不严谨,就会造成以非正常的方式让出控制权的问题。

  • 创建一个安全的系统绝不简单,这总是需要对安全性和功能性进行权衡,一个系统越安全,它的用处就越小。

    不论你的应用程序有多好,如果目标系统不安全,那么你的程序也会受到攻击:

  • 不要在你的计算机上运行任何非受信的、可能不安全的程序。
  • 运用防火墙、垃圾邮件与病毒过滤器等安全技术。
  • 记录所有的操作、操作者和操作时间,以防止恶意的受信用户。
  • 尽量减少进入系统的途径,为每个用户分配最小的权限。
  • 正确的设置系统,某些操作系统默认使用非常不严格的安全性。
  • 安装一个“蜜罐”:一台比你真正的系统更容易受到攻击者入侵的诱饵机器。

    安全性必须是系统的体系结构和设计的一个基本组成部分,方法包括:

  • 限制设计中的输入数量,并且安排所有的通信都通过系统的某个部分进行。
  • 在尽可能低的权限等级上运行每个程序。
  • 避免开发任何你并不真正需要的功能。
  • 不要依赖于不可靠的库,只依赖于已知的、安全的第三方组件。
  • 是你的代码适应可以管理安全问题的执行环境。
  • 避免存储敏感数据。
  • 从用户处获取机密信息时要小心。
  • 最无效的一种安全策略就是“不公开,即安全”,不公开不意味着不为至关重要的计算机系统宣称,并希望没有任何攻击者可以找到它。

    当我们已经构建了一个设计精良的体系结构后,还必须使用安全的代码来构建坚固的防御,正确的代码不一定是安全的代码:

  • 防御性编程是实现可靠代码的主要技术。它的中心原则“不做设想”就是一种安全的编程方式。
  • 执行安全审核。由安全专家对源代码进行认真的审查。
  • 在产生子进程时要非常谨慎。
  • 严格的执行测试和调试。
  • 将所有操作都打包到原子事务中,这样攻击者就无法利用竞争条件来获利。

  • 我们必须要教给用户一些安全的工作习惯:不要把密码告诉任何人,不要在重要的计算机上随意安装软件,以及只按照规定的方法来使用系统。

  • 安全性是一个很现实的问题,采取鸵鸟的方式对存在的漏洞置之不理,只会导致更严重的结果。

  • 优秀的程序员:1. 了解他们所参与的每个项目的安全需求;2.
    会本能的写出避免常见安全漏洞的代码;3.
    将安全性设计到每个系统,不会在最后才给它们打补丁;4.
    拥有一种安全性测试的策略。

  • 糟糕的程序员:1. 认为安全性不是一个重要的问题;2.
    把自己当成安全专家;3.
    只在发现漏洞,甚至是代码被破坏之后,才考虑他们程序中的安全缺陷;4.
    在编写代码时关注安全性,但是在设计和体系结构层面上忽略了安全性。

相关文章