HTML 或脚本不可能蒙混过此正则表达式!不要使用正则表达式寻找无效字符并在发现这种无效字符后拒绝请求,因为轻易出现漏掉的情况。 第二种防范措施是对所有作为输出的输入进行 HTML 编码。这会减少危险的 HTML 标记,使之变成更安全的转义符。您可以在 ASP.NET 中使用 HttpServerUtility.HtmlEncode,或者在 ASP 中使用 Server.HTMLEncode 转义任何可能出现问题的字符串。
void DoQuery(string Id) { SqlConnection sql=new SqlConnection(@"data source=localhost;" + "user id=sa;password=password;"); sql.Open(); sqlstring= "SELECT hasshipped" + " FROM shipping WHERE id='" + Id + "'"; SqlCommand cmd = new SqlCommand(sqlstring,sql); ???
这段代码有三个严重缺陷。首先,它是以系统治理员帐户 sa 建立从 Web 服务到 SQL Server 的连接的。不久您就会看到这样做的缺陷所在。第二点,注重使用“password”作为 sa 帐户密码的聪明做法! 但真正值得关注的是构造 SQL 语句的字符串连接。假如用户为 ID 输入 1001,您会得到如下 SQL 语句,它是完全有效的。
SELECT hasshipped FROM shipping WHERE id = '1001'
但攻击者比这要有创意得多。他们会为 ID 输入一个“'1001' DROP table shipping --”,它将执行如下查询:
SELECT hasshipped FROM shipping WHERE id = '1001' DROP table shipping -- ';
这时您也许会觉得希奇,怎么任何一个用户都能删除 SQL Server 数据库中的表呢。当然,您是对的,只有治理员才能做这样的工作。但这里您是作为 sa 连接到数据库的,而 sa 能在 SQL Server 数据库上做他想做的任何事。永远不要在任何应用程序中以 sa 连接 SQL Server;正确的做法是,假如合适,使用 Windows 集成的身份验证,或者以一个预先定义的具有适当权限的帐户连接。
假如没有百分之九十以上的用户要求,则不应默认安装某一功能。Internet">Internet">Internet">Internet Information Services (IIS) 6.0 遵循了这一安装建议,您可以在这个月发布的 Wayne Berry 的文章“Innovations in Internet">Internet">Internet">Internet Information Services Let You Tightly Guard Secure Data and Server Processes”中读到相关内容。这种安装策略背后的思想是您不会注重自己并未使用的服务,假如这些服务正在运行,则可能被其他人利用。假如默认安装某功能,则它应在最小授权原则下运行。也就是说,除非必要,否则不要答应使用治理员权限运行应用程序。最好遵循这一忠告。 QQread.com 推出各大专业服务器评测 linux服务器的安全性能 SUN服务器 HP服务器 DELL服务器 IBM服务器 联想服务器 浪潮服务器 曙光服务器 同方服务器 华硕服务器 宝德服务器 7. 使用最小授权原则
出于若干原因,操作系统和公共语言运行时有一个安全策略。很多人以为此安全策略存在的主要原因是防止用户有意破坏:访问他们无权访问的文件、重新配置网络以达到他们的要求以及其他恶劣行为。的确,这种来自内部的攻击很普遍,也需要防范,但还有另一个原因需要严守这一安全策略。即在代码四周建立起防范壁垒以防止用户有意或(正如经常发生的)无意的操作对网络造成严重破坏。例如,通过电子邮件下载的附件在 Alice 的机器上执行时被限制为只能访问 Alice 可以访问的资源。假如附件中含有特洛伊木马,那么好的安全策略就是限制它所能产生的破坏。 当您设计、建立并部署服务器应用程序时,您不能假设所有请求都来自合法用户。假如一个坏家伙发送给您一个恶意请求(但愿不会如此)并使您的代码产生恶劣操作,您会希望您的应用程序拥有所有可能的防护来限制损害。因此我们认为,您的公司实施安全策略不仅是因为它不信任您或您的代码,同时也是为了保护不受外界有企图的代码的伤害。
为您的服务器代码选择一个安全环境,仅答应其访问完成其工作所必需的资源。假如您代码中的某些部分要求很高的权限,请考虑将这部分代码分离出来并单独以较高的权限运行。为安全分离这一以不同的操作系统验证信息运行的代码,您最好在一个单独的进程(运行在具有更高权限的安全环境中)中运行此代码。这意味着您将需要进程间通讯(如 COM 或 Microsoft .NET 远程处理),并且需要设计该代码的接口以使往返行程最小。
编写服务器应用程序时,您经常会发现自己直接或间接使用了 Windows 的一个称为模拟的很方便的功能。模拟答应进程中的每个线程运行在不同的安全环境中,通常是客户端的安全环境。例如,当文件系统重定向器通过网络收到一个文件请求时,它对远程客户端进行身份验证,检查以确认客户端的请求没有违反共享上的 DACL,然后把客户端的标记附加到处理请求的线程上,从而模拟客户端。然后此线程便可以使用客户端的安全环境访问服务器上的本地文件系统。由于本地文件系统已经是安全的,因此这样做很方便。它会考虑所请求的访问类型、文件上的 DACL 和线程上的模拟标记来进行一个访问检查。假如访问检查失败,本地文件系统会将其报告给文件系统重定向器,然后重定向器向远程客户端发送一个错误。毫无疑问,对文件系统重定向器来说这很方便,因为它只是简单地把请求传给本地文件系统,让它去做自己的访问检查,就好象客户端在本地一样。 这对于文件重定向器这样简单的网关而言,一切良好。但模拟经常用在其他更复杂的应用程序中。以一个 Web 应用程序为例。假如您编写一个经典的非托管 ASP 程序、ISAPI 扩展或 ASP.NET 应用程序,在它的 Web.config 文件中有如下指定
<identity impersonate='true'>
那么您的运行环境将有两种不同的安全环境:您将具有一个进程标记和一个线程标记,一般来说,线程标记会被用来做访问检查(见图 )。假设您正在编写一个在 Web 服务器进程中运行的 ISAPI 应用程序,并假定大多数请求未经身份验证,则您的线程标记可能是 IUSR_MACHINE,而进程标记却是 SYSTEM!假设您的代码能被一个坏家伙通过缓冲区溢出利用。您认为他会只满足作为 IUSR_MACHINE 运行吗?当然不会。他的攻击代码很可能会调用 RevertToSelf 以删除模拟标记,从而希望提高他的权限级别。在这种情况下,他会很轻易获得成功。他还可以调用 CreateProcess。它不会从模拟标记复制新进程的标记,而是从进程标记复制,这样新进程便可以作为 SYSTEM 运行。
那么怎样解决这个小问题呢?除了首先确保不出现任何缓冲区溢出外,还要记住最小授权原则。假如您的代码不需要具有 SYSTEM 这样大的权限,则不要将 Web 应用程序配置为在 Web 服务器进程中运行。假如只是将 Web 应用程序配置为在中等或较高的隔离环境中运行,您的进程标记将会是 IWAM_MACHINE。您实际上没有任何权限,因而这种攻击几乎不会生效。注重,在 IIS 6.0(即将成为 Windows .NET Server 的一个组件)中,默认情况下用户编写的代码不会作为 SYSTEM 运行。基于这样的熟悉,即开发人员确实会犯错误,Web 服务器就减少赋予代码的权限而提供的任何帮助都是有益的,以免万一代码中存在安全问题。
下面是另外一个 COM 程序员可能碰到的隐患。COM 有一个不好的倾向就是敷衍线程。假如您调用一个进程内 COM 服务器,而其线程模型与调用线程的模型不匹配,则 COM 会在另一个线程上执行调用。COM 不会传播调用者线程上的模拟标记,这样结果就是调用会在进程的安全环境中执行,而不是在调用线程的安全环境中。多么令人吃惊!