本单元从威胁、对策、缺陷、攻击的角度来分析 Web 应用程序安全。当结合安全性特性设计、实现和部署应用程序时,这有助于更好地理解攻击者的想法。从攻击者的角度考虑问题,并了解他们的可能手段,在采取对策时会更有效。本单元介绍传统的攻击者采用的方法,并对典型的攻击进行剖析。
本单元开始介绍了攻击者使用的常见方法,以危及 Web 应用程序的安全,并建议采用 STRIDE 方法对威胁进行分类。然后,介绍了可能危及网络、主机基础结构和应用程序安全的主要威胁。了解这些威胁和适当的对策,为威胁建模过程提供了重要的信息。
本单元使您可以找出在特定情况下的具体威胁,并根据它们对系统构成的危险程度区分优先次序。
目标
使用本单元:
-
开始以攻击者的方式考虑问题。
-
了解常用于对威胁进行分类的 STRIDE 方法。
-
识别与对抗网络、主机和应用程序级威胁。
应用于
Web 应用程序
如何使用本单元
本单元找出了一组常用的网络、主机和应用程序级威胁,并找出了应对每种威胁建议采取的对策。
本单元没有对威胁进行详细列表,但重点介绍了多种主要威胁。有了这些攻击者如何进行操作的信息和知识,您就可以识别其他的威胁。
您需要了解最可能影响系统的威胁,这样就可以构建有效的威胁模型。这些威胁模型是“威胁建模”单元的主题。
要想充分利用本单元:
-
熟悉影响网络、主机与应用程序的具体威胁。尽管攻击者的目标可能是一样的,但威胁对于系统的各个不同部分来说是特有的。
-
利用威胁识别危险并规划对这些威胁的对抗措施。
-
对缺陷采取对策。本单元对对策进行了总结。利用本手册的第 3 部分,“构建安全 Web 应用程序”,和第 4 部分,“保护网络、主机和应用程序”,了解实现对策的详细情况。
当设计、构建并保护新的系统时,要考虑本单元概述的威胁。这些威胁的存在与平台或者使用的技术无关。
本页内容
开始之前
剖析攻击
了解威胁分类
网络威胁与对策
主机威胁与对策
应用程序威胁与对策
输入验证
身份验证
授权
配置管理
敏感数据
会话管理
加密技术
参数操作
异常管理
审核和日志记录
小结
其他资源
开始之前
开始威胁建模过程之前,了解下面的基本术语非常重要:
-
资源。有价值的资源,如数据库或者文件系统的数据,或者系统资源。
-
威胁。潜在事件 — 恶意的或者其他方式 — 可能会损害资源。
-
缺陷有可能造成威胁的缺陷
-
攻击(或者利用)。所采取的损害资源的行为
-
对策。一种 应对威胁与减轻危险的保护措施
剖析攻击
通过了解以 Web 应用程序为目标时攻击者使用的基本方法,您将可以更好地配备防护措施,因为您知道您的对手是什么。攻击者方法的基本步骤总结如下,并用图 1 进行说明:
-
调查与评估
-
利用与渗透
-
提高特权
-
维护访问
-
拒绝服务
调查与评估
按顺序进行调查与评估潜在的目标。通常,攻击者采取的第一步就是调查潜在的目标,以确定和评估它的特点。这些特点可能包括,它支持的服务和协议,以及潜在的缺陷和入口点。攻击者利用在调查与评估阶段收集的信息来规划首次攻击。
例如,通过测试来查看 Web 页中的任何控件是否会对输出进行回应,攻击者可能检测到一个跨站点脚本编写 (XSS) 缺陷。
利用与渗透
调查完潜在的目标后,下一步就是利用与渗透。如果网络和主机已经完全地保护起来,您的应用程序(前门)就成为下一个攻击渠道。
对于攻击者,进入应用程序的最简单方法就是通过合法用户使用的同一入口 — 例如,通过应用程序的登录页或者不需要身份验证的网页。
提高特权
攻击者设法危害应用程序或者网络之后,他们会立即尝试通过将代码注入应用程序或者利用 Windows® 2000 操作系统创建一个身份验证会话,以提高特权。特别是,他们会寻求帐户提供管理特权,这些帐户是管理员组的成员。他们还寻求本地系统帐户提供的高级特权。
在整个应用程序中使用最小特权服务帐户是防护特权提高攻击的主要手段。同时,许多网络级提高特权攻击需要一个交互登录会话。
维护访问
可以访问系统后,攻击者还要采取措施以使将来访问时更轻松,并可以掩饰他的或她的踪迹。使将来可以更轻松访问的常见方法包括,安置后门程序或者利用缺乏严格保护的现有帐户。掩饰踪迹通常包括清除日志和隐藏工具。这样,审核日志就是攻击者的一个主要目标。
应当保护日志文件,还应定期分析日志文件。分析日志文件经常可以在损失造成之前发现早期的尝试闯入的迹象。
拒绝服务
不能进行访问的攻击者经常会安置一个拒绝服务攻击,阻止其他人使用这个应用程序。对于其他攻击者,从一开始拒绝服务选择就是他们的目标。SYN Flood 攻击就是一个例子,攻击者利用一个程序来发送大量的 TCP SYN 请求,以填充服务器上挂起的连接队列。这就阻止了其他用户建立网络连接。
了解威胁分类
由于具体的攻击和攻击技术有许多变体,因此根据攻击者试图实现的目标来考虑威胁是十分有用的。这就将注意的焦点从识别每一种具体的攻击 — 这确实是达到目标的一种手段,改变为注意可能攻击的目标结果。
STRIDE
可以根据攻击的目标和目的对应用程序面临的威胁进行分类。有关威胁分类的应用知识有助于您组织安全策略,这样您就可以有计划地对威胁进行回应。STRIDE 是 Microsoft 使用的对不同威胁类型进行分类的首字母缩写词。STRIDE 代表:
-
欺骗。欺骗 就是试图通过使用假身份访问系统。这可以通过使用盗窃来的用户凭据或者假 IP 地址而实现。当攻击者以合法用户或者主机的身份成功访问系统后,就可以开始提高特权或者滥用授权了。
-
篡改。篡改 就是未经授权就对数据进行更改,例如当数据流过两个计算机间的网络时。
-
否认。否认 就是用户(合法的或者非法的)否认他们曾执行过特定操作或者事务的能力。审核不足,则很难检验否认攻击。
-
信息泄漏。信息泄漏不必要地暴露私有数据。例如,用户查看他或者她没有被授权打开的表或者文件的内容,或监视通过网络传输的、明文形式的数据。一些信息泄漏缺陷的示例包括,使用隐藏的窗体字段、嵌入在 Web 页中的注释包含有数据库连接字符串和连接细节,以及可能导致暴露给客户端的内部系统级别细节的差劲的异常处理。这些信息对攻击者来说都是非常有用的。
-
拒绝服务。拒绝服务 就是使系统或者应用程序不可使用的过程。例如,拒绝服务攻击可以这样实现:通过请求来冲击服务器,以消耗掉所有的系统可用资源,或者通过给服务器传递格式错误的输入数据以使一个应用程序进程崩溃。
-
提高特权。提高特权 在这样的情况下就会出现:具有有限特权的用户假冒特权用户的身份来对应用程序进行特权访问。例如,具有有限特权的攻击者可能会提高他的或者她的特权级别来损害并控制更高特权与受信任的进程或帐户。
STRIDE 威胁与对策
STRIDE 所描述的每一类威胁都具有一套对应的对抗技术,应当使用这些技术来降低危险。表 1 对这些技术进行了小结。对策适当与否取决于特定的攻击。稍后,本单元将对网络、主机以及应用程序级的更多威胁、攻击和采用的对策进行介绍。
表 1 STRIDE 威胁与对策 威胁 | 对策 |
---|---|
盗用用户身份 | 使用强身份验证。 |
篡改数据 | 使用数据散列法与签名。 |
否认 | 创建安全的审计追踪。 |
信息泄漏 | 使用强授权。 |
拒绝服务 | 使用资源与带宽调节技术。 |
提高特权 | 遵循最低特权原则,并使用最低特权服务帐户运行进程以及访问资源。 |
网络威胁与对策
构成网络基础结构的主要组件有路由器、防火墙和交换机。它们担当网关守卫的角色,保护您的服务器和应用程序不受攻击与入侵。攻击者可能使用配置很差的网络设备。常见的缺陷包括脆弱的默认安装设置、对外开放的访问控制以及缺少最新安全补丁的设备。主要的网络级威胁包括:
-
信息收集
-
探查
-
欺骗
-
会话劫持
-
拒绝服务
信息收集
可以用与其他类型系统相同的方法发现网络设备并对其进行剖析。通常,攻击者最初是扫描端口。识别出开放端口后,他们利用标题抓取与枚举的方法检测设备类型,并确定操作系统和应用程序的版本。具有这些信息后,攻击者可以攻击已知的缺陷,这些缺陷可能没有更新安全补丁。
阻止信息收集的对策包括:
-
配置路由器,限制它们对足迹请求的响应。
-
配置承载网络软件(例如,软件防火墙)的操作系统,通过禁用不使用的协议和不必要的端口,可以阻止足迹。
探查
探查 或者窃听 就是监视网络上数据(例如明文密码或者配置信息)传输信息的行为。利用简单的数据包探测器,攻击者可以很轻松地读取所有的明文传输信息。同时,攻击者可以破解用轻量级散列算法加密的数据包,并解密您认为是安全的有用负荷。探查数据包需要在服务器/客户端通信的通道中安装数据包探测器。
帮助阻止探查的对策包括:
-
使用强有力的物理安全措施并适当对网络进行分段。这是阻止传输信息在本地被收集的第一步。
-
通信完全加密,包括对凭据的身份验证。这可以防止攻击者使用探查到的数据包。SSL 与 IPSec(Internet 协议安全性)就是这种加密解决方案的示例。
欺骗
欺骗就是一种隐藏某人在网上真实身份的方式。为创建一个欺骗身份,攻击者要使用一个伪造的源地址,该地址不代表数据包的真实地址。可以使用欺骗来隐藏最初的攻击源,或者绕开存在的网络访问控制列表(ACL,它根据源地址规则限制主机访问)。
虽然不可能根据精心制作的欺骗数据包追踪到原始的发送者,但是组合筛选规则可以防止欺骗数据包起源于您的网络,使您可以拦截明显的欺骗数据包。
防止欺骗的对策包括:
-
筛选看上去是来自周边内部 IP 地址的传入数据包。
-
筛选看上去是源于无效本地 IP 地址的外出数据包。
会话劫持
也称为中间人攻击,会话劫持欺骗服务器或者客户端接受:上游主机就是真正的合法主机。相反,上游主机是攻击者的主机,它操纵网络,这样攻击者的主机看上去就是期望的目的地。
帮助防止会话劫持的对策包括:
-
使用加密的会话协商。
-
使用加密的通信通道。
-
及时获取有关平台补丁的信息,修补 TCP/IP 缺陷,例如可预测的数据包序列。
拒绝服务
拒绝服务就是拒绝合法用户访问服务器或者服务。SYN FLOOD 攻击就是网络级拒绝服务攻击的常见示例。该攻击容易发起并且不容易追踪。攻击的目的是给服务器发送大量的请求,从而超过它的处理能力。该攻击利用的是 TCP/IP 连接建立机制中的一个潜在缺陷,并冲击服务器的挂起连接队列。
防止拒绝服务的对策包括:
-
使用最新的服务包。
-
通过应用适当的注册表设置强化 TCP/IP 堆栈,以增大 TCP 连接队列的大小,缩短建立连接的周期,并利用动态储备机制来确保连接队列永远不会耗尽。
-
使用网络入侵检测系统 (IDS),因为这可以自动检测与回应 SYN 攻击。
主机威胁与对策
主机威胁针对构建应用程序的系统软件。这包括 Windows 2000、Internet 信息服务 (IIS)、.NET Framework 和 SQL Server 2000,是哪一种取决于特定的服务器角色。主要的主机级威胁包括:
-
病毒、特洛伊木马和蠕虫
-
足迹
-
剖析
-
破解密码
-
拒绝服务
-
任意执行代码
-
未授权访问
病毒、特洛伊木马和蠕虫
病毒就是一种设计的程序,它进行恶意的行为,并破坏操作系统或者应用程序。除了将恶意的代码包含在表面上是无害的数据文件或者可执行程序中外,特洛伊木马很像一种病毒。除了可以从一个服务器自我复制到另一个服务器,蠕虫类似于特洛伊木马。蠕虫很难检测到,因为它们不是定期创建可以看见的文件。通常只有当它们开始消耗系统资源时,才能注意到它们,因为这时系统运行缓慢或者其他执行的程序停止运行。红色代码蠕虫就是最臭名远扬、攻击 IIS 的蠕虫,它的存在依靠的是某特定 ISAPI 筛选器中的缓冲区溢出缺陷。
虽然这三种威胁是实实在在的攻击手段,同时它们会对 Web 应用程序、这些应用程序所在的主机以及用来传递这些应用程序的网络造成重大的威胁。通过许多缺陷,例如默认设置的脆弱性、软件错误、用户错误和 Internet 协议固有的缺陷,这些攻击在任何系统上都有可能取得成功。
用来对付病毒、特洛伊木马和蠕虫的对策包括:
-
保持当前采用最新的操作系统服务包和软件补丁。
-
封锁防火墙和主机的所有多余端口。
-
禁用不使用的功能,包括协议和服务。
-
强化脆弱的默认配置设置。
足迹
足迹的示例有端口扫描、ping 扫描以及 NetBIOS 枚举,它可以被攻击者用来收集系统级的有价值信息,有助于准备更严重的攻击。足迹揭示的潜在信息类型包括帐户详细信息、操作系统和其他软件的版本、服务器的名称和数据库架构的详细信息。
帮助防止足迹的对策包括:
-
禁用多余的协议。
-
用适当的防火墙配置锁定端口。
-
利用 TCP/IP 与 IPSec 筛选器来进行更深一步的防护。
-
配置 IIS,防止通过标题抓取泄漏信息。
-
配置 IDS,利用它获取足迹模式并拒绝可疑的信息流。
破解密码
如果攻击者不能够与服务器建立匿名连接,他或者她将尝试建立验证连接。为此,攻击者必须知道一个有效的用户名和密码组合。如果您使用默认的帐户名称,您就给攻击者提供了一个顺利的开端。然后,攻击者只需要破解帐户的密码即可。使用空白或者脆弱的密码可以使攻击者的工作更为轻松。
帮助防止破解密码的对策包括:
-
所有的帐户类型都使用强密码。
-
对最终用户帐户采用锁定策略,限制猜测密码而重试的次数。
-
不要使用默认的帐户名称,重新命名标准帐户,例如管理员的帐户和许多 Web 应用程序使用的匿名 Internet 用户帐户。
-
审核失败的登录,获取密码劫持尝试的模式。
拒绝服务
可以通过多种方法实现拒绝服务,针对的是基础结构中的几个目标。在主机上,攻击者可以通过强力攻击应用程序而破坏服务,或者攻击者可以知道应用程序在其上寄宿的服务中或者运行服务器的操作系统中存在的缺陷。
帮助防止拒绝服务的对策包括:
-
配置应用程序、服务和操作系统时要考虑拒绝服务问题。
-
保持采用最新的补丁和安全更新。
-
强化 TCP/IP 堆栈,防止拒绝服务。
-
确保帐户锁定策略无法被用来锁定公认的服务帐户。
-
确信应用程序可以处理大流量的信息,并且该阀值适于处理异常高的负荷。
-
检查应用程序的故障转移功能。
-
利用 IDS 检测潜在的拒绝服务攻击。
任意执行代码
如果攻击者可以在您的服务器上执行恶意的代码,攻击者要么就会损害服务器资源,要么就会更进一步攻击下游系统。如果攻击者的代码所运行的服务器进程被越权执行,任意执行代码所造成的危险将会增加。常见的缺陷包括脆弱的 IID 配置以及允许遍历路径和缓冲区溢出攻击的未打补丁的服务器,这两种情况都可以导致任意执行代码。
帮助防止任意执行代码的对策包括:
-
配置 IIS,拒绝带有“../”的 URL,防止遍历路径的发生。
-
利用严格的 ACL,锁定系统命令和实用工具。
-
保持使用最新的补丁和更新,确保新近发现的缓冲区溢出尽快打上补丁。
未授权访问
不足的访问控制可能允许未授权的用户访问受限制信息或者执行受限制操作。常见的缺陷包括,脆弱的 IIS Web 访问控制,这又包括 Web 权限和脆弱的 NTFS 权限。
帮助防止未授权访问的对策包括:
-
配置安全的 Web 权限。
-
利用受限制的 NTFS 权限锁定文件和文件夹。
-
使用 ASP.NET 应用程序中的 .NET Framework 访问控制机制,包括 URL 授权和主要权限声明。
应用程序威胁与对策
分析应用程序级威胁的较好方法就是根据应用程序缺陷类别来组织它们。本单元随后几节使用的以及贯穿本手册的不同类别威胁,与应用程序的主要威胁都小结在表 2 中。
根据应用程序缺陷划分的威胁类别列表 类别 | 威胁 |
---|---|
输入验证 | 缓冲区溢出,跨站点脚本编写,SQL 注入,标准化 |
身份验证 | 网络窃听,强力攻击, |
授权 | 提高特权,泄漏机密数据,篡改数据,引诱攻击 |
配置管理 | 未经授权访问管理接口,未经授权访问配置存储器,检索明文配置数据,缺乏个人可记帐性,越权进程和服务帐户 |
敏感数据 | 访问存储器中的敏感数据;窃听网络;篡改数据 |
会话管理 | 会话劫持;会话重放;中间人 |
加密技术 | 密钥生成或密钥管理差;脆弱的或者自定义的加密术 |
参数操作 | 查询字符串操作;窗体字段操作;cookie 操作;HTTP 标头操作 |
异常管理 | 信息泄漏;拒绝服务 |
审核和日志记录 | 用户拒绝执行某项操作;攻击者利用没有跟踪记录的应用程序;攻击者掩饰他或者她的跟踪记录 |
输入验证
如果攻击者发现,您的应用程序没有设定输入数据的类型、长度、格式或者范围,输入验证就成为了一个安全问题。然后,攻击者就可以提供精心打造的输入,这会损害您的应用程序。
如果网络和主机级的入口点被完全保护起来,应用程序公开的公用接口就成为唯一的攻击源。应用程序输入既是测试系统的一种手段,也是为攻击者执行代码的一种方式。您的应用程序是否盲目地信任输入?如果是这样,您的应用程序可能会很容易受下列因素的影响:
-
缓冲区溢出
-
跨站点脚本编写
-
SQL 注入
-
标准化
-
下一节将详细考察这些缺陷,这包括什么因素有可能造成这些缺陷。
缓冲区溢出
缓冲区溢出缺陷可以导致拒绝服务攻击或者代码注入。拒绝服务攻击可以引起进程崩溃;代码注入可以更改程序的执行地址,从而运行攻击者的注入代码。下面的代码片段说明了一种常见的缓冲区溢出缺陷的示例。
void SomeFunction( char *pszInput ) { char szBuffer[10]; // Input is copied straight into the buffer when no type checking is performed strcpy(szBuffer, pszInput); . . . }
托管 .NET 代码不受此问题的影响,因为当访问数组时会自动检查数组边界。这样就使得缓冲区溢出攻击的威胁对于托管代码就不算什么问题。但是仍然要关注它,特别是在托管代码调用非托管 API 或者 COM 对象的场合。
帮助防止缓冲区溢出的对策包括:
-
执行完全的输入验证。这是防护缓冲区溢出的首要对策。尽管您的应用程序中可能存在一个错误,它允许期望的输入超出容器的边界,但意外的输入仍是引起缺陷的主要原因。通过验证输入的类型、长度、格式和范围,对输入进行约束。
-
如果有可能,限制您的应用程序使用非托管代码,并彻底检查非托管 API,确保输入得到正确验证。
-
检查调用非托管 API 的托管代码,确保只有适当的数值才能作为参数传递给非托管 API。
-
利用 /GS 标志来编译用 Microsoft Visual C++_ 开发系统开发的代码。/GS 标志能使编译器将安全检查插入到被编译的代码中。这不是一种预防失败的解决方案,或者要替代专用的验证代码;但是,它确实可以保护您的代码不受众所周知的缓冲区溢出的攻击。有关更多信息,请参阅 .NET Framework 产品文档:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vclrfGSBufferSecurity.asp 和 Microsoft 知识库文章 325483“支持 WebCast:编译器安全检查:/GS 编译器开关”,网址为: http://support.microsoft.com/default.aspx?scid=325483。
通过缓冲区溢出注入代码的示例
攻击者可以利用缓冲区溢出缺陷来注入代码。利用这种攻击,恶意的用户通过提供一个精心构建的输入值,以改写程序的堆栈并修改函数的返回地址,从而利用某个进程中未检查的缓冲区。这就使执行跳到了攻击者的注入代码处。
通常,攻击者的代码最终在进程的安全上下文处运行。这就强调了使用最低特权进程帐户的重要性。如果当前的线程正在模拟,攻击者代码最终就会在该线程的模拟标记定义的安全上下文处运行。通常,攻击者做的第一件事就是调用 RevertToSelf API,以恢复攻击者希望具有更高特权的进程级安全上下文。
确信您已验证了输入的类型和长度,特别是在调用非托管代码之前,因为非托管代码特别易受缓冲区溢出的影响。
跨站点脚本编写
当浏览器和某个可信的 Web 站点连接时,XXS 攻击可以引起任意代码在用户的浏览器中运行。攻击的目标为应用程序的用户而非应用程序本身,但是它以您的应用程序作为攻击的工具。
由于是从一个可信的站点用浏览器下载了脚本代码,浏览器无从知道这些代码是非法的。Internet Explorer 的安全区不能提供任何防护。由于攻击者的代码可以访问与可信站点相关的 cookie,这些 cookie 存储在用户的本地计算机上。一般情况下,用户的身份验证 cookie 就成为了攻击的目标。
跨站点脚本编写示例
为发起攻击,攻击者必须说服用户单击某个精心打造的超级链接,例如,在发送给用户的电子邮件中嵌入一个链接,或者将恶意链接添加到某新闻组记录中。应用程序中有缺陷页的链接点将未验证的输入以 HTML 输出流的形式返回到浏览器中。例如,考虑下面的两个链接。
这是一个合法的链接:
www.yourwebapplication.com/logon.aspx?username=bob
这是一个恶意链接:
www.yourwebapplication.com/logon.aspx?username=<script>alert ('hacker code')</script>
如果 Web 应用程序要获取查询字符串,但未能恰当地验证它,然后就将其返回给浏览器,脚本代码就在浏览器中执行。前面的例子会弹出一条无害的消息。利用适当的脚本,攻击者就可以轻易抽取用户的身份验证 cookie,并将它寄回他的站点,随后就以经身份验证用户的身份对目标 Web 站点产生一个请求。
防止 XSS 的对策包括:
-
执行完全的输入验证。您的应用程序必须确保来自查询字符串、窗体字段和 cookie 的输入对于应用程序来说是合法的。将所有的用户输入都认为可能是恶意的,筛选或者清理下游代码的上下文。验证所有的输入是否为已知的有效值,然后拒绝其他所有的输入。用正则表达式验证通过 HTML 窗体字段、cookie 和查询字符串而接收到的输入数据。
-
利用 HTMLEncode 和 URLEncode 函数对包括用户输入在内的任何输出进行编码。这就将可执行脚本转换成无害的 HTML。
SQL 注入
SQL 注入式攻击利用输入验证中的缺陷来运行数据库中的任意命令。当应用程序使用输入来构造访问数据库的动态 SQL 语句时就会发生这种攻击。如果您的代码使用存储过程,传递给该过程的字符串中包含有未筛选的用户输入时,也会发生这种攻击。利用 SQL 注入攻击,攻击者可以执行数据库中的任意命令。如果应用程序使用一个越权帐户来与数据库连接,问题会更严重。在这种情况下,除了能够检索、操作和破坏数据外,利用数据库服务器来运行操作系统命令是可能的,并有可能危及其他服务器的安全。
SQL 注入的示例
当您将未验证的用户输入合并到数据库查询中时,您的应用程序可能受到 SQL 注入攻击。特别容易受到攻击的是利用未筛选用户输入构造动态 SQL 语句的代码。考虑下面的代码:
SqlDataAdapter myCommand = new SqlDataAdapter( "SELECT * FROM Users WHERE UserName ='" + txtuid.Text + "'", conn);
通过在单引号字符后跟一个分号字符来开始一条新命令来终止计划中的 SQL 语句,然后执行他们选择的命令,攻击者可以进行 SQL 注入攻击。考虑输入到 txtuid 字段中的下列字符串。
'; DROP TABLE Customers–
这会导致将下面的语句提交给数据库执行。
SELECT * FROM Users WHERE UserName=''; DROP TABLE Customers --'
这将会删除 Customers 表,假设应用程序的登录对数据库有足够的权限(这是使用最低特权登录数据库的另一原因)。双破折号 (--) 表示 SQL 注释,并用来对程序员添加的任何其他字符如结尾引号进行注释。
注 分号实际上不是必需的。SQL Server 将执行由空格分开的两条命令。
可以运用一些其他更微妙的技巧。将下列输入提供给 txtuid 字段:
' OR 1=1–
构建下列命令:
SELECT * FROM Users WHERE UserName='' OR 1=1–
由于 1=1 总为 true,攻击者要检索 Users 表中的每行数据。
防止 SQL 注入的对策包括:
-
执行完全的输入验证。应用程序在将请求发送给数据库之前要对输入进行验证。
-
利用参数化存储过程来访问数据库,确保不会将输入字符串看作是可执行语句。如果不能使用存储过程,在构建 SQL 命令时要利用 SQL 参数。
-
利用最低特权帐户来与数据库连接。
标准化
将不同形式的输入转化成相同的标准名称(规范名称),这被称为标准化。如果代码是根据传递给程序的资源名称(它作为输入)来进行安全决策,这样的代码就特别容易受到标准化问题的影响。文件、路径和 URL 都是容易受标准化影响的资源类型,因为每种情况都有许多表示相同名称的不同方法。文件名称也有这样的问题。例如,可以将一个文件表示为:
c:\temp\somefile.dat somefile.dat c:\temp\subdir\..\somefile.dat c:\ temp\ somefile.dat ..\somefile.dat
理想情况下,代码不予接受文件名输入。如果确实要接受,应当在进行安全决策前将该名称转换成规范形式的名称,例如是否同意或者拒绝访问指定的文件。
针对标准化问题的对策包括:
-
尽可能避免将文件名称作为输入,而是使用最终用户不能更改的绝对文件路径。
-
确信文件名称格式正确(如果必须接受将文件名称作为输入的话),并且要在应用程序上下文内对其进行验证。例如,检查它们是否在您的应用程序的目录层次结构内。
-
确保字符编码设置正确,以限制输入的表示方法。检查您的应用程序的 Web.config 是否已经在 <globalization> 元素中设置了 requestEncoding 与 responseEncoding 属性。
身份验证
根据您的需求,有几种身份验证机制供选择。如果选择和实现不正确,身份验证机制就会暴露出缺陷,攻击者利用这些缺陷可以访问您的系统。利用身份验证缺陷造成的主要威胁包括:
-
网络窃听
-
强力攻击
-
词典攻击
-
Cookie 重放攻击
-
盗窃凭据
网络窃听
如果将身份验证凭据以明文形式从客户端传递到服务器,在同一网络的某台主机上配备有基本网络监控软件的攻击者可以捕获传递的信息并获取用户的名称和密码。
防止网络窃听的对策包括:
-
使用不在网络上传输密码的身份验证机制,例如 Kerberos 协议或者 Windows 身份验证机制。
-
确信密码已加密(如果必须在网络上传输密码的话),或者使用加密的通信通道,例如 SSL。
强力攻击
强力攻击依靠计算能力来破解散列的密码或者破解其他用散列和加密保护的秘密。为降低风险,可以使用强密码。
词典攻击
利用这种攻击可以获得密码。大多数密码系统不存储明文密码或者加密密码。它们避免使用加密密码是因为,危及安全的密钥可以损害数据存储区中的所有密码。丢失了密钥意味着所有的密码都无效。
大多数用户存储含有密码散列值(或者摘要)的实现。根据用户提供的密码值重新计算散列值,并将它与存储在数据库中的散列值进行比较,以此来验证用户的身份。如果攻击者设法获得了散列密码列表,就能够使用强力攻击来破解密码散列值。
利用词典攻击,攻击者利用一个程序循环访问字典中的所有的单词(或多种语言的多个字典)并计算每个单词的散列值。将获得的散列值与数据存储区中的值进行比较。脆弱密码,例如“Yankees”(一个喜爱的团队)或者“Mustang”(一辆喜欢的轿车),将会很快被破解。较强的密码,例如“?You'LlNevaFiNdMeyePasSWerd!”,被破解的可能性要小一些。
注 一旦攻击者获得了散列密码列表,可以离线进行词典攻击,并且不需要与应用程序进行交互。
防止词典攻击的对策包括:
-
使用复杂、非寻常的单词作为强密码,并且是包含大小写、数字和特殊字符的混合体。
-
在用户的存储器中存储非可逆的散列密码。同时散列密码要组合一个有力的数值(一个加密的强随机数)。
有关存储添加有力数值散列密码的更多信息,请参阅 “构建安全的数据访问。”
Cookie 重放攻击
-
利用这类攻击,攻击者可以利用监控软件捕获用户的身份验证 cookie,并且将它重放给应用程序以便能够以假身份进行访问。
-
防止 cookie 重放的对策包括:
-
当传输身份验证 cookie 时,使用 SSL 提供的加密通信通道。
-
利用一个 cookie 超时时间值,强迫在某个相对短的时间间隔后进行身份验证。虽然这种方法不能防止进行重放攻击,但它减小了攻击者重放请求的时间间隔,这期间无需强迫进行再次身份验证,因为会话已经超时。
盗窃凭据
如果应用程序在实现自己的用户存储时包含有用户的帐户名称和密码,将它的安全性与由平台提供的凭据存储(例如,Microsoft Active Directory 的目录服务或者安全帐户管理器 (SAM) 的用户存储)的安全性进行比较。浏览器的历史记录和缓存也存储有将来使用的用户登录信息。如果是除了登录者的其他用户访问该终端,并且点击同一个网页,就可以使用已经保存的登录。
帮助防止盗窃凭据的对策包括:
-
使用和执行强密码。
-
以添加有力的数值的散列值存储密码检验值。
-
在固定次数重试后对最终用户帐户执行帐户锁定。
-
为了杜绝浏览器缓存允许登录访问的可能性,可以创建这样的功能,该功能既可以允许用户选择不保存凭据,又可以将该功能强制成为默认的策略。
授权
根据用户的身份和角色成员身份,对特殊的资源或者服务进行授权,要么允许访问,要么拒绝访问。利用授权缺陷的主要威胁包括:
-
提高特权
-
机密数据泄漏
-
篡改数据
-
引诱攻击
提高特权
在设计授权模型时,必须要考虑攻击者试图提升特权,以成为一个超级帐户如本地管理员组成员或者本地系统帐户的威胁。这样做,攻击者就完全能够控制应用程序和本地计算机。例如,利用传统的 ASP 编程,从一个组件调用 RevertToSelf API 可能会造成正在执行的线程以本地系统帐户身份运行,而该本地系统帐户拥有本地计算机的超级特权。
可以用来防止提升特权的主要对策就是使用最低特权进程、服务和用户帐户。
机密数据泄漏
如果未授权用户可以查看敏感数据,就会发生机密数据泄漏的问题。机密数据包括应用程序专用的数据,例如信用卡号、雇员详细资料、财务记录等,还包括应用程序配置数据,例如服务帐户凭据以及数据库连接字符串。为了防止泄漏机密数据,应在网络上传输时对其进行保护,还应在持久性存储区中进行保护(例如数据库和配置文件)。只有经过身份验证和授权的用户才能访问他们专用的数据。应当限制只有管理员才能访问系统级配置数据。
防止泄漏机密数据的对策包括:
-
在允许访问可能暴露敏感数据的操作之前,进行角色检查。
-
利用强 ACL 来保护 Windows 资源。
-
利用标准的加密技术将敏感数据存储到配置文件和数据库中。
篡改数据
篡改数据是指未经授权就更改数据。
防止篡改数据的对策包括:
-
利用强访问控制以保护在持久性存储区中的数据,确保只有授权的用户才可以访问和更改数据。
-
使用基于角色的安全策略来区分用户,谁可以查看数据,谁可以更改数据。
引诱攻击
当几乎没有特权的实体可以让具有更多特权的实体代表它执行操作时,就会发生引诱攻击。
为了对抗这种威胁,必须通过适当的授权来限制对可信代码的访问。只要访问安全资源或者执行特权操作,都要授权调用代码。.NET Framework 的代码访问安全机制在这方面会有所帮助。
配置管理
许多应用程序支持配置管理界面和功能,以允许操作者和管理员更改配置参数,更新 Web 站点的内容,以及进行日常的维护。主要的配置管理威胁包括:
-
未经授权访问管理界面
-
未经授权访问配置存储区
-
检索明文配置秘密
-
缺乏个人可记帐性
-
越权进程和服务帐户
未经授权访问管理界面
经常通过另外的 Web 页或者单独的 Web 应用程序提供管理界面,它允许管理员、操作者和内容开发人员来管理站点内容和配置。这些管理界面只应当由有限的和授权的用户使用。恶意的用户能够访问配置管理功能可能会破坏 Web 站点、访问下游系统和数据库,或者通过破坏配置数据而使应用程序出现故障。
防止未授权访问管理界面的对策包括:
-
将管理界面的数量减到最少。
-
使用强身份验证,例如,使用证书。
-
使用带有多个网关守卫的强授权。
-
考虑只支持本地管理。如果完全需要远程管理,那么利用加密通道,例如,VPN 技术或者 SSL,这是由于在管理界面上传递的数据的敏感性所导致的。为了进一步降低风险,还要考虑使用 IPSec 策略来限制对 Internet 网络上的计算机进行远程管理。
未经授权访问配置存储区
由于配置存储区中维护的数据的敏感性,应当确保存储区得到了足够的保护。
保护配置存储区的对策包括:
-
配置基于文本的配置文件(例如 Machine.config 与 Web.config)中的受限的 ACL。
-
保持自定义的配置存储区位于 Web 空间之外。这样就消除了下载 Web 服务器配置以利用其缺陷的可能性。
检索明文配置秘密
必须要限制访问配置存储区。作为深层次机制中的一种重要防护措施,应当对诸如密码和连接字符串的敏感数据进行加密。这有助于防止外部攻击者获取敏感配置数据。这还可以防止不道德的管理员和内部员工获得敏感详细资料,例如数据库连接字符串以及帐户凭据,这些可能会允许他们访问其他系统。
缺乏个人可记帐性
缺乏对更改配置信息的审核和日志记录就会威胁识别以下情况的能力:什么时候进行的更改以及谁做的更改。当由诚实操作者的错误或者恶意的更改导致出现中断更改,从而允许特权访问时,首先要采取行动纠正这些修改。然后采取预防措施,防止以同样的方式引入中断更改。要牢记,共享帐户可以躲避审核和日志记录,这对管理帐户与用户/应用程序/服务帐户都适用。不能共享管理帐户。分配用户/应用程序/服务帐户的级别时必须允许使用该帐户标识单一的访问源,并考虑对赋予该帐户的特权的破坏。
越权应用程序和服务帐户
如果允许应用程序和服务帐户更改系统上的配置信息,它们可能会受攻击者的操纵而这样做。通过采取使用最低特权服务和应用程序帐户的策略,可以降低这种威胁带来的风险。要慎重授予帐户更改它们自己配置信息的能力,除非设计有明确的要求。
敏感数据
敏感数据遭受各种威胁。试图查看或者更改敏感数据的攻击目标是持久性存储区和网络。对敏感数据的主要威胁包括:
-
访问存储区的敏感数据
-
网络窃听
-
篡改数据
访问存储区的敏感数据
必须要保护存储区的敏感数据,以防止恶意的或者其他的用户访问和读取这些数据。
保护存储区的敏感数据的对策包括:
-
对包含敏感数据的持久性数据存储区使用受限 ACL。
-
存储加密数据。
-
使用基于身份和角色的授权,确保只有具有适当授权级别的用户才允许访问敏感数据。用基于角色的安全机制来区分用户,谁可以查看数据,谁可以更改数据。
网络窃听
Web 应用程序的 HTTP 数据以明文的形式在网络上传输,并遭受网络窃听攻击,攻击者利用网络监视软件捕获并有可能更改敏感数据。
防止网络窃听并提供私密性的对策包括:
-
加密数据。
-
使用加密通信通道,例如,SSL。
篡改数据
篡改数据指的是未经授权就更改数据,通常发生在数据在网络上传输时。
防止篡改数据的一条对策就是用防篡改协议,如散列消息身份验证代码 (HMAC) 来保护在网络上传输的敏感数据。
HMAC 以下面的方式提供消息完整性:
-
发送方利用共享的密钥创建基于消息有效负载的散列值。
-
发送方将散列值和消息有效负载一道传输。
-
接收方利用共享的密钥重新计算基于接收到的消息有效负载的散列值。然后,接收方将新散列值与传输的散列值进行比较。如果它们一样,消息就没有被篡改。
会话管理
Web 应用程序的会话管理是应用程序层的一项职责。会话的安全性对于应用程序的整体安全性非常重要。
主要的会话管理威胁包括:
-
会话劫持
-
会话重放
-
中间人
会话劫持
当攻击者利用网络监视软件捕获用来表示用户与应用程序进行会话的身份验证标记(通常是一个 cookie)时,就会发生会话劫持攻击。利用捕获的 cookie,攻击者可以欺骗用户会话,访问应用程序。攻击者具有和合法用户同级的特权。
防止会话劫持的对策包括:
-
利用 SSL 创建一条安全的通信通道,并只在 HTTPS 连接上传输身份验证 cookie。
-
实现注销功能,允许用户在启动另一个会话时结束强制身份验证会话。
-
如果不使用 SSL,确保要限制会话 cookie 的有效期。虽然这不能防止会话劫持,但是它减小了攻击者可利用的时间。
会话重放
当用户的会话标记被攻击者中途截取和提交以绕过身份验证机制时,就会发生会话重放。例如,如果会话标记为 cookie 或者 URL 中的明文,攻击者可以探查到它。然后,攻击者利用被劫持的会话标记来发出请求。
帮助解决会话重放威胁的对策包括:
-
当执行关键功能时,重新进行身份验证。例如,在银行应用中传输金融信息之前,让用户再次提供帐户密码。
-
使会话经适当时间后过期,包括所有的 cookie 和会话标记。
-
创建“不要提醒我”选项,不允许客户端存储会话数据。
中间人攻击
当攻击者拦截在您和您期望的接收者之间发送的消息时,就会发生中间人攻击。然后,攻击者更改您的消息并将它发送给原来的接收者。接收者接收到消息而且认为是您发送的,并对之采取行动。当接收者给您发回消息,攻击者拦截它、更改它,再发送给您。您和您的接收者永远不会知道您们已经被攻击。
涉及客户端与服务器间的通信的任何网络请求,包括 Web 请求、分布式组件对象模型 (DCOM) 请求以及调用远程组件和 Web 服务,这些都会遭到中间人攻击。
防止中间人攻击的对策包括:
-
使用加密技术。如果在传输数据之前对数据加密,攻击者虽然还可以拦截它,但却不能阅读或更改它。如果攻击者不能阅读它,他或她就不知道更改哪一部分。如果攻击者盲目地更改加密消息,那么原来的接收者就不能成功地进行解密,这样就知道数据已经被篡改。
-
使用散列消息身份验证代码 (HMAC)。如果攻击者更改这种消息,接收者重新计算 HMAC 就会失败,然后就会拒绝这种无效数据。
加密技术
大多数应用程序利用加密技术来保护数据,确保它的私密性并不被更改。围绕应用程序使用加密技术的主要威胁包括:
-
糟糕的密钥生成或者密钥管理机制
-
脆弱的或者自定义的加密技术
-
校验和欺骗
糟糕的密钥生成或者密钥管理机制
如果攻击者得到密钥或者可以推导出密钥,他们就可以解密加密的数据。如果不妥善管理密钥或者不以随机的方式产生密钥,攻击者就可以找出密钥。
应对糟糕的密钥生成和密钥管理机制的威胁的对策包括:
-
使用内置的加密例程,这种例程包含安全密钥管理。数据保护应用程序编程接口 (DPAPI) 就是一个加密服务示例,它由 Windows 2000 及其以后的操作系统提供,其中操作系统管理密钥。
-
使用强随机密钥生成函数,并将密钥存储在一个受限制的地方 — 例如,存储在用受限制的 ACL 保护的注册表密钥中 — 如果使用需要生成或管理密钥的加密机制。
-
用 DPAPI 加密密钥,增加安全性。
-
定期使密钥过期。
脆弱的或者自定义的加密技术
如果加密技术被破解或者很容易被强力破解,加密算法就不具有安全性。如果没有经过测试,自定义的算法特别容易受到攻击。相反,要使用公布的、著名的加密算法,它们都经受住了多年的苛刻攻击和审查。
针对脆弱的或者自定义的加密技术容易受到攻击的对策包括:
-
不开发自己自定义的算法。
-
使用由平台提供、经受考验的加密服务。
-
了解被破解的算法和用来破解算法的技术。
校验和欺骗
不要依靠通过散列来提供网络上发送的消息的数据完整性。散列,例如安全散列算法 (SHA1) 和消息摘要压缩算法 (MD5) 可能被拦截和更改。考虑下面的 base 64 编码并附加消息身份验证代码 (MAC) 的 UTF-8 消息:
Plaintext: Place 10 orders. Hash: T0mUNdEQh13IO9oTcaP4FYDX6pU=
如果通过监视网络,攻击者拦截了消息,攻击者就可以修改该消息并重新计算散列值(猜测您使用的算法)。例如,该消息可能被更改为:
Plaintext: Place 100 orders. Hash: oEDuJpv/ZtIU7BXDDNv17EAHeAU=
当接收者处理该消息时,它们通过散列算法运行明文 (“Place 100 orders”),然后重新计算散列值,他们计算的散列值将会等于攻击者计算的散列值。
为了对抗这种攻击,可以使用 MAC 或者 HMAC。用消息身份验证代码三倍数据加密标准 (MACTripleDES) 算法计算 MAC,而用 HMACSHA1 计算 HMAC。两种算法都使用一个密钥来产生校验和。对于这些算法,攻击者需要知道产生校验和的密钥,接收者将会正确计算校验和。
参数操作
操作参数攻击是一种依靠更改在客户端和 Web 应用程序之间发送的参数数据的攻击。这包括查询字符串、窗体字段、cookie 和 HTTP 标头。主要的操作参数威胁包括:
-
操作查询字符串
-
操作窗体字段
-
操作 cookie
-
操作 HTTP 标头
操作查询字符串
用户很容易就可以操作由 HTTP GET 传递的从客户端到服务器的查询字符串值,因为它们显示在浏览器的 URL 地址栏中。如果您的应用程序依靠查询字符串值来进行安全决策,或者如果该值代表的是诸如资金数量的敏感数据,那么该应用程序就很容易受到攻击。
应对操作查询字符串威胁的对策包括:
-
避免使用包含敏感数据或者影响服务器安全逻辑的查询字符串参数。相反,要使用会话标识符来标识客户端,并将敏感项存储在服务器上的会话存储区中。
-
选用 HTTP POST 来代替 GET 提交窗体。
-
加密查询字符串参数。
操作窗体字段
HTML 窗体的字段值是以明文形式利用 HTTP POST 协议发送到服务器的。这可能包括可见的和隐藏的窗体字段。任何类型的窗体字段都可以轻松地被更改,并可以绕过客户端的验证例程。结果,服务器上依靠窗体字段输入值来进行安全决策的应用程序很容易受到攻击。
对抗操作窗体字段的威胁要使用会话标识符来引用服务器状态存储区中维护的状态,而不是使用隐藏的窗体字段。
操作 cookie
Cookie 很容易被客户端更改。这对于持久 cookie 和驻留内存的 cookie 都是如此。有许多工具可以帮助攻击者更改驻留在内存的 cookie 的内容。操作 cookie 攻击是指更改 cookie,通常是为了访问未授权的 Web 站点。
虽然 SSL 可以保护网络上的 cookie,但它不能阻止在客户端计算机上更改 cookie。为了对抗操作 cookie 威胁,使用加密或者 HMAC cookie。
操作 HTTP 标头
HTTP 标头在客户端和服务器之间传递信息。客户端构造请求标头,而服务器构造响应标头。如果您的应用程序依靠请求标头来进行决策,您的应用程序就很容易受到攻击。
不要根据 HTTP 标头进行安全决策。例如,不要信任 HTTP Referer 来确定客户来自何处,因为它很容易被篡改。
异常管理
允许传播给客户端的异常可以泄漏内部实现的详细资料,它对最终用户没有意义,但对攻击者却非常有用。不使用异常处理或者异常处理实现得非常糟糕的应用程序,也会遭受拒绝服务攻击。主要的异常处理威胁包括:
-
攻击者发现实现的详细资料
-
拒绝服务
攻击者发现实现的详细资料
.NET Framework 的一个重要特点就是提供丰富的异常详细资料,这些资料对于开发人员具有极大价值。如果这同样的信息落到攻击者的手中,它将会大大帮助攻击者利用潜在的缺陷以及规划将来的攻击。可以被返回的信息类型包括平台版本、服务器名称、SQL 命令字符串以及数据库连接字符串。
帮助防止内部实现详细资料泄漏给客户端的对策包括:
-
在整个应用程序代码库中使用异常处理。
-
处理和记录允许传播到应用程序边界的异常。
-
返回给客户端一般的无害错误消息。
拒绝服务
攻击者通常通过故意传递格式错误的输入来探测 Web 应用程序。在他们的脑海中经常有两个目标。第一个是引起异常的发生,以泄漏有用的信息。第二个是破解 Web 应用程序进程。如果异常没有被正确地捕捉到和处理,就会发生这种情况。
帮助防止应用程序级拒绝服务的对策包括:
-
彻底验证服务器的所有输入数据。
-
在整个应用程序代码库中使用异常处理。
审核和日志记录
应当使用审核和日志记录来帮助发现可疑的活动,例如足迹或者真正攻击之前的可能破解密码企图。它还有助于处理否认威胁。如果多个服务器上的一系列同步日志条目表明用户执行过某项交易,那么用户就很难否认执行过这项操作。
与审核和日志记录有关的主要威胁包括:
-
用户否认执行过某项操作
-
攻击者攻击某应用程序而没有留下踪迹
-
攻击者掩饰他们的踪迹
用户否认执行过某项操作
否认问题就是用户否认他或她执行过某个操作或者发起过某项交易。需要适当的防护机制来确保可以追踪和记录所有的用户活动。
帮助防止否认威胁的对策包括:
-
审核和记录 Web 服务器与数据库服务器以及应用程序服务器(如果使用的话)上的活动。
-
记录主要事件,如交易、登录和注销事件。
-
不要使用共享帐户,因为这样不能确定最初的源。
攻击者攻击某应用程序而没有留下踪迹
需要进行系统和应用程序级审核,以确保未漏掉可疑的活动。
发现可疑活动的对策包括:
-
记录重要的应用程序级操作。
-
利用平台级审核来审核登录和注销事件、访问文件系统以及失败的对象访问尝试。
-
备份日志文件,并定期分析可疑活动的征兆。
攻击者掩饰他们的踪迹
要很好地保护好您的日志文件,以确保攻击者不能掩饰他们的踪迹。
帮助防止攻击者掩饰他们踪迹的对策包括:
-
使用受限制的 ACL 来保护日志文件。
-
将系统日志文件从默认的位置重新定位。
小结
了解了攻击者使用的典型方法和它们的目标,您在采用对策时就可以更加有效。这还有助于在考虑和识别威胁时使用基于目标的方法,并有助于使用 STRIDE 模型来根据攻击者的目标对威胁进行分类,例如,盗用身份、篡改数据、拒绝服务、提高特权等等。这就使您可以将精力更多地集中在用来降低风险的一般方法上,而不是将精力集中在识别每一种可能的攻击上,那可能是一项耗时但很可能无收效的做法。
本单元已经为您介绍了主要的威胁,它们可能会危及您的网络、主机基础结构和应用程序的安全。这些威胁还有适当的对策知识为威胁建模过程提供基本的信息。它使您能够识别特殊场合下特有的威胁,并且能够根据它们对系统造成的风险程度区分优先次序。这种识别和区分威胁优先次序的结构化过程被称为威胁建模。有关更多信息,请参阅“威胁建模。”
其他资源
更多有关的材料,请参阅下面的资源:
-
有关网络威胁与对策的更多信息,请参阅“保护网络”单元。
-
有关主机威胁与对策的更多信息,请参阅“保护 Web 服务器”、“保护应用程序服务器”、“保护数据库服务器”以及“保护 ASP.NET 应用程序”等单元。
-
有关本单元中提出的应对应用程序级威胁的更多信息,请参阅本手册第 3 部分的构建单元,“构建安全的 Web 应用程序”。
-
Michael Howard 与 David LeBlanc Writing Secure Code 2nd Edition.Microsoft 出版社,雷蒙德市,华盛顿州,2002
-
有关跟踪与修复缓冲区溢出的更多信息,请参阅 MSDN 上的文章,“Fix Those Buffer Overruns!”,Web 站点为 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncode/html/secure05202002.asp。