首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

许,有多少程序员,就有多少关于安全性的想法。对于安全性,不一定有必然正确的做法,但是,这里必定有大量错误的做法。

关于安全性首先要理解的一点是,没有彻底安全的应用程序。如果你能够让应用程序安全,就必定在某处有某人能挫败你的努力并“偷偷潜入”系统中。然而,即便有这样的认识,为了把讨厌的入侵者阻挡在系统之外,依然要努力实现这一目标。好消息是,大多数情况下,你能够很容易地让事情变得十分费劲,以致99.999%的人不想为此劳神。至于另外的那0.001%的人,我只能鼓励你去确信你所有的雇员都热爱生活,这使得他们属于99.999%的那类人。这0.001%的人有望访问到其他一些地方。

在SQL Server 2005中,微软对于SQL Server的安全性非常重视。这里有大量的新特性,并且,尽管以前已经有专门针对SQL Server安全性的书籍,但是现在,我可以想见,它们将是更加庞大的长篇大论——在这个版本中,该主题的内容大大增加了。

本章中,我们将讲述下面的内容:

l    安全性基础;

l    SQL Server安全性选项;

l    数据库和服务器角色;

l    应用程序角色;

l    凭据;

l    模式管理;

l    XML集成安全性问题;

l    更高级的安全性。

我们将发现,这里有大量不同的方法来处理安全性问题。安全性不仅仅是给某人一个用户ID和密码——你会看到有许多问题需要考虑。

在开始本章的任何示例之前,需要载入并执行名为NorthwindSecure.sql脚本。这个脚本会创建一个特别的数据库,我们将在本章使用该数据库。可以从本书的网站www.wrox.com下载学习所需要的东西。

是的,为了运行本章的示例,我不得不让你创建一个工作数据库——很抱歉。这里将使用的是旧的Northwind数据库,只不过要删除所有对权限的修改。我们将在整个这一章中使用的NorthwindSecure数据库,它是一种更典型的数据库场景——即是说,除了随着创建表和对象自然带来的权限外,绝对没有添加任何权限(即没有)。随着本章讲述的深入,我们将学习如何处理权限,以及如何明确添加想要的权限。

22.1  安全性基础

我相信,就我们将在本节中查看的内容而言,有相当一部分似乎极为愚蠢——我的意思是,这些东西难道不是尽人皆知的吗?然而,即便是这些规则中最简单的一个,违背它的情形也屡屡发生,从这些频繁发生的对规则的违反来判断,我要说,“不,显然它们不是。”所有我能做的就是请你耐心一些,不要跳过这里的内容。这里的某些内容看起来似乎很显而易见,但令人吃惊的是,它们常常被忘记或者被忽略。

在种种基础知识中,这里要讨论的是:

l    一个人,一个登录名,一个密码;

l    密码过期;

l    密码长度和组成;

l    尝试登录的次数;

l    用户ID和密码信息的存储。

22.1.1  一个人,一个登录名,一个密码

不断让我感到震惊的事情是,无论我到哪里,几乎总能发现机构中至少有一个“全局的”用户——网络或者特定的应用程序中的某个登录,该登录经常被部门或者甚至整个公司里几乎所有的人所知道。通常,这个“全局的”用户拥有全权的(换言之,完全的)访问权。对于SQL Server来说,安装甚至不把sa的密码设置为非空白的密码,这在过去是很平常的。

在SQL Server 2000之前,sa账户的默认密码是空密码——即是说,它没有密码。谢天谢地,SQL Server 2000不仅改变了这种默认情况,而且,现在SQL Server还会预先告知,如果你坚持让该密码为空白,那你一定是不折不扣的白痴——这对开发团队十分有益。需要当心的事情是,在进行开发时,还是会将它设置得很“简便”,这确实是很普遍的现象。在投入生产之前,你还必须记住对它进行修改,或者,如果开发服务器将直接暴露在因特网上或暴露给其他不可信的访问,则必须从一开始就将它设置得很困难。

即使现在,当多数的安装都的确有了非空的密码时,许多人知道密码是什么的情形也极为普遍。

那么,第一个基础知识是,如果所有的人都能访问某个用户ID,则该用户ID本质上是匿名的(如果所有的人都知道它,则任何人都有可能使用它),并且能访问任何事情,那么,你已经彻底击败了你的安全模型。同样,如果给每一个用户一个在所有事情上拥有完全访问权限的登录名,则也已经严重破坏了安全前景。剩下的唯一真正的好处是,对于任何时刻谁有关联的问题,能够说出显著的人(假设他们确实使用了他们个人的登录名,而不是使用全局的登录名)。

应当把拥有全权访问权限的用户限制为仅仅一、两个人。理想的情况是,如果需要这种全权访问的密码,那么,你会想要不同的登录名各自拥有这样的访问权,而对于每一个登录名来说,只会有一个人知道其密码。

你将发现,用户常常与其他人共享他们的密码,以便让某人临时获得某种级别的访问(通常,这是由于该登录ID的所有者要么在休假,要么在那时没有时间,以致无法亲自去完成此事)——如果可能的话,应当严禁这样做。

由共享密码导致的问题是多方面的。第一,一些用户获得了对某些事物的访问权,而这种访问权最初是决定不给予他们的(否则,为什么他们自己没有这种必要的权限呢?)——如果以前不准备让他们访问,现在为什么又想让他们访问了呢?第二,不允许进行访问的用户现在可能暂时拥有了访问权。由于用户几乎从不更换他们的密码(除非强迫他们这样做),被给予密码的人员多半能不定期地使用那个登录ID——并且,我向你保证,他们一定会的!第三,你再次失去了审核。你可能有一些基于登录ID来跟踪哪一个用户做了什么的东西。如果有不止一个人有那个登录ID的密码,如何分辨在某个时候是哪一个人用那个登录ID登录进来的呢?

这就意味着,如果有人在某个时候将不在办公室,这或许是因为此人生病了,或者在度假,那么,将由另外的人临时接替此人去完成其工作,于是,应当明确为那个接替的人创建新的登录ID和密码(或者,应当修改其现有登录ID的访问权限),然后,一旦原来的人返回工作岗位,则应当删除新的登录ID。

总之,尽量别碰全局的用户账户。如果必须使用它们,则要把它们的使用限制在尽可能少的人之中——通常,应当保持在仅仅两个人(一个是主要的使用者,而另一个是在第一个人无法完成任务的情况下作为候补之用)。如果确实必须让不止一个人有重要的访问权,那么,可以考虑创建多个具有必要的访问权限的账户(一人一个账户)。遵照这些简单的步骤,就能为系统的安全性和审核做出大量的贡献。

22.1.2  密码过期

密码过期的使用往往倾向于要么被滥用,要么被忽视。因为它是一个很好的主意,但常常会变得不利。

密码过期背后的原理是:对系统进行设置,使密码经过一段特定的时间后会自动过期。在到达时间期限后,用户必须更改密码才能继续访问账户。这一概念已经存在了许多年,如果你在较大的公司里工作,来自会计师事务所的审计师很可能已经在强调:必须实现某种形式的密码过期。

从SQL Server 2005开始,如今,你甚至可以为SQL Server专用密码强制使用Windows安全策略机制。或者,你也可以只使用基于Windows的安全性(下一节中将有更多有关的内容)。

1.做这些努力,收益是什么

那么,密码过期能让你得到什么?还记得我在前一节的最后说过,一旦密码被共享,用户将始终拥有那种访问权吗?好吧,这里是例外的情况。如果让密码过期,那么,就更新了安全级别——至少暂时如此。为了让用户重新得到访问权,可能必须再次共享密码。尽管这远远不算完美(该登录ID的拥有者经常会很乐意再次共享它),但当密码的共享确实只为了一次性的使用时,这的确处理了这种情况。通常,数月之后,共享他们密码的用户甚至不会意识到共享了密码;而另外的用户手里依然有密码,并且,可能间或会使用一下这个密码,以获得他们自身的安全级别所不应拥有的访问权。

2.下面是不利之处

好事做过了头,很可能变成坏事。我在前面说过,许多会计师事务所都希望他们的客户实现这样的模式:用户的密码会有规律地过期,例如,每30天——实际上,这是很糟的主意。

在我见过的所有这样做了的SQL Server安装中(无一例外),执行了30天过期的策略后,安全性变得更糟了。正如你可能想象的那样,问题本质上是多方面的。

l    第一,技术支持的需求大大增多了。当用户如此频繁地更改密码时,他们完全不能记住所有这些密码。他们无法记住应该使用哪一个月的密码,由于忘记了密码是什么,因而经常需要技术支持来重置密码。

l    第二,这一点更为重要,用户对于想出新密码并记住它们感到厌烦。经验显示,在使用了30天过期策略的安装中,90%以上的用户把他们的密码改成具有惊人的可预测性的(因而是可被入侵的)单词或者单词和数字的组合。事实上,这常常发展到这种程度:50%或者更多的用户使用相同的密码——他们都使用类似MMMYY的东西作为密码,其中MMM是月份,而YY是年份。例如,在1996年一月,他们可能使用JAN96作为密码。很快,这里的所有人都会做这样的事情。

我曾见过一些公司试图通过实施密码嗅探器(当要更改密码时,它会检查密码)来应对这种情况。嗅探进程寻找混合了姓名或以月份前缀开头的密码。这种机制再好,其作用也是很微弱的。

用户远比你想象的聪明。多数用户大约用一星期就能规避第一个嗅探器——他们只不过把密码更改为以“X”为前缀,这样就能继续使用以前所用的MMMYY格式了。简言之,嗅探器最终所起的作用微乎其微。

这里的实质问题并非要避免使用过期策略。应当使密码过期的时间足够短,以获得合适的新旧更替并应对共享或窃取密码的情况,但是,又不能太频繁,否则会导致用户产生抗拒心理并开始使用弱密码。我个人建议过期的时间要多于90天但少于180天。

22.1.3  密码长度和组成

在这一领域,应为SQL Server感到欢欣鼓舞。在以前的版本中,如果使用SQL Server安全性,则实际上对这一方面做不了多少控制。现在,能够让SQL Server使用Windows密码策略(可以通过Windows中的实用工具进行调整)。

1.密码长度

要知道,用户每在密码中包含进一个可能的字母数字位,可能的密码数量就将至少增加36倍(实际上,倘若包含特殊的字符则会更多一些,但是,在这里,即使36倍也足以说明问题)。这意味着,对于一个字符的密码来说,仅有36种可能性,但两个字符的密码将有1296种可能性。如果密码包含的字符数增加到3个,可能性将增长到46 656。当向密码中加入第4个字符时,可能性将超过一百万种。随着要求密码包含的字符数越来越多,排列的方式也不断增加。当然,如果处处都要求超过5或6个字符,那么,终端用户将产生极大的反感。

2.密码组成

是的,我已经指出过,如果要求使用至少4位字母数字的密码,则在这种情况下,将有超过百万种可能的密码组合。其实,人们不会使用所有这些组合(他们将使用熟悉的单词或者名字),当你意识到这一点时,问题就来了。考虑到一般人经常使用的单词只有5000个左右,因而对于想要入侵的人来说,并不需要尝试太多的单词即可得逞。

如果你实施的不是默认的Windows密码策略,那么,要考虑要求至少一个字符是字母的(不是数字,只是字母),同时,至少一个字符是数字的。简单的数字(实际上,人们喜欢使用他们的社会安全号、电话号码或生日)以及完全的单词都很容易被猜到,这排除了这种可能性。用户依然能够创建对于他们来说很容易记住的密码——如“77pizzas”,但是,这样的密码不可能从字典里找出。为了尝试并入侵,任何黑客都不得不真正尝试每一种组合。

22.1.4  尝试登录的次数

无论物理上如何存储用户和密码信息,登录界面都应当与之有联系,从而限制某人尝试登录的次数。当用户超过了登录限制时,做出反应的程度可以是不同的,但是,要确保有某种方法,让用程序的方式尝试所有密码的做法变得很困难。

只要允许的登录尝试的次数是比较小的数值,究竟允许多少次其实并不是那么重要——我通常使用3次,但是,我也在一些地方见过用4和5次的,而那样也是不错的。

如果执行的是Windows密码策略,那么SQL Server将相对于错误密码限制来检查登录尝试并强制该策略。

22.1.5  用户和密码信息的存储

显然,仅当你使用自己的安全系统而不是使用内置的Windows和(或)SQL Server安全系统时(但许多Web应用程序将会这样做),这才适用,而且,在大多数时候,如何存储用户配置和密码信息并不是什么高深的学问。尽管如此,这里还是有几件事情需要考虑:

l    由于需要能在最初获得信息,你必须做如下三件事情之一:

编译密码到客户端应用程序或组件中(然后,确保在你安装应用程序的服务器上创建了正确的登录名和密码)。

利用SQL Server新的加密技术在数据库中加密和解密数据。

要求某种双密码的情形——一个让用户到达常规的密码信息,而另一个让用户到达真正的应用程序。通常,迫使用户两次登录让人无法接受,因而,在大多数情况下,你会返回到其他两种选择之一。

l    如果处于要使用双密码的场景中,可能的话,将会想要把第一个登录的访问限制在只能执行存储过程上。通过这样做,能够允许第一个登录获得其所需要的验证,但不会把任何东西暴露给试图通过Management Studio登录的任何人。使你的存储过程(sproc)接受用户ID和密码,并且,只传回布尔值(能够登录真或假)或者传回一个记录集,记录集中列出了用户能够在客户端看到什么窗口和函数。如果使用原始的SELECT语句,则无法对用户能够看到的事情进行限制。
我曾实现过的类似这种场景的方案是,用一个视图把当前SQL Server登录映射到其他登录信息。在这种情况下,应用程序角色用来让应用程序获得对所有事情的完全访问权——应用程序必须知道用户能够和不能够做什么。该存储过程如下所示:

l    如果你准备把密码信息存储在系统中——请加密密码!!!这一点我无论强调多少次也不过分。多数用户会把密码用在不止一件事情上——当需要记住的事情较少时,生活会容易得多。通过在数据被放入到数据库中之前对数据进行加密,确保了没有人会知晓用户的密码信息——即使是偶然得到。他们可能会看到它,但是,如果没有解密的密钥,他们所看到的没有任何用处。

实际上,在SQL Server 2005中,几乎没有理由不加密数据。现在,我们有大量非常、非常安全的加密选项可用(在本章的后面将有更多相关的内容)——请使用它们!

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论