黑客攻防技术宝典:Web实战篇(第2版)
上QQ阅读APP看书,第一时间看更新

2.3 处理攻击者

任何设计安全应用程序的开发人员必须基于这样一个假设:应用程序将成为蓄意破坏且经验丰富的攻击者的直接攻击目标。能够以受控的方式处理并应对这些攻击,是应用程序安全机制的一项主要功能。这些机制通常结合使用一系列防御与攻击措施,以尽可能地阻止攻击者,并就所发生的事件,通知应用程序所有者以及提供相应的证据。为处理攻击者而采取的措施一般由以下任务组成:

❑ 处理错误;

❑ 维护审计日志;

❑ 向管理员发出警报;

❑ 应对攻击。

2.3.1 处理错误

不管应用程序开发者在确认用户输入时多么小心,还是几乎可以肯定会出现一些无法预料的错误。功能与用户验收测试过程能够查明普通用户行为造成的错误,在生产环境中部署应用程序前应当考虑到这一因素。然而,我们无法预测恶意用户与应用程序交互的每一种可能方式,并且当应用程序遭受攻击时肯定会出现其他错误。

应用程序的一个关键防御机制是合理地处理无法预料的错误,要么纠正这些错误,要么向用户发送适当的错误消息。在生产环境下,应用程序不应在其响应中返回任何系统生成的消息或其他调试信息。过于详细的错误消息非常有利于恶意用户向应用程序发动进一步攻击。有些情况下,攻击者能够利用存在缺陷的错误处理方法从错误消息中获得敏感信息;此时,错误消息成为攻击者从应用程序中窃取数据的重要渠道。图2-6显示了一个由无法处理的错误生成的过于详细的错误消息。

图2-6 一个无法处理的错误

大多数Web开发语言通过try-catch块和受查异常提供良好的错误处理支持。应用程序代码应广泛使用这些方法查明特殊与常规错误,并做出相应处理。而且,还可以配置大多数应用程序服务器,使其以自定义的方式处理无法处理的应用程序错误,如提供不包含太多信息的错误消息。请参阅第15章了解有关这些措施的更多详情。

有效的错误处理措施通常与应用程序的日志机制整合在一起,后者尽可能地记录与无法预料的错误有关的调试信息。通常,无法预料的错误往往能够指明应用程序的防御机制中存在的缺陷。如果应用程序的所有者获得必要的信息,就能从源头解决这些问题。

2.3.2 维护审计日志

审计日志(audit log)在调查针对应用程序的入侵尝试时会发挥很大作用。发生入侵后,有效的审计日志功能应能够帮助应用程序所有者了解实际发生的情况,如哪些漏洞(如果有)被加以利用,攻击者是否可以对数据进行非法访问或执行任何未授权的操作,并尽可能地提供侵入者的身份信息。

在任何注重安全的应用程序中,日志应记录所有重要事件。一般这些事件应至少包括以下几项。

❑ 所有与身份验证功能有关的事件,如成功或失败的登录、密码修改。

❑ 关键交易,如信用卡支付与转账。

❑ 被访问控制机制阻止的访问企图。

❑ 任何包含已知攻击字符串,公然表明恶意意图的请求。

许多安全性至关重要的应用程序(如电子银行使用的应用程序)会完整记录客户端提出的每一个请求,这样可为任何事故调查提供全面的司法记录。

有效的审计日志功能一般会记录每个事件的发生时间、发出请求的IP地址和用户的账户(如果通过验证)。这些日志必须受到严格保护,避免未授权的读取或写入访问。一种有效的保护方法是将审计日志保存在仅接受主应用程序送出的更新消息的自治系统中。某些情况下,可能需要将日志复制到一次性写入的媒质中,确保它们的完整性,以便在遭受攻击后进行调查。

在受攻击面方面,保护不严密的审计日志可能为攻击者提供大量信息,向其披露许多敏感信息,如会话令牌和请求参数,这些信息可能会使攻击者能够立即攻破整个应用程序(见图2-7)。

图2-7 保护不严密、包含其他用户提交的敏感信息的应用程序日志

2.3.3 向管理员发出警报

审计日志可帮助应用程序所有者调查入侵企图,如有可能,应对侵入者采取法律行动。然而,许多时候我们希望立即采取行动,实时响应攻击企图。例如,管理员可能会阻止被攻击者利用的IP地址或用户账户。在极端情况下,他们甚至可能在调查攻击、采取补救措施时将应用程序从网络中断开。这时,即使攻击者已经成功侵入应用程序,如果能够及时采取防御措施,也可以将实际影响降到最低。

许多时候,警报机制必须在两个相互矛盾的目标之间取得平衡,既准确报告每次的真实攻击,又不会生成过多警报,造成它们被管理员忽略。精心设计的报警机制能够组合各种因素,确定应用程序正在遭受的某种攻击;并在可能的情况下将所有相关事件集中到一个警报中。警报监控的反常事件一般包括以下几种。

❑ 应用反常,如收到由单独一个IP地址或用户发出的大量请求,表明应用程序正受到自定义攻击。

❑ 交易反常,如单独一个银行账户所转入或转出的资金数量出现异常。

❑ 包含已知攻击字符串的请求。

❑ 请求中普通用户无法查看的数据被修改。

现有的应用程序防火墙和入侵检测产品能够相当完善地提供其中一些功能。这些产品一般组合应用一组基于签名与异常的规则来确定对应用程序的恶意利用,并能够主动阻止恶意请求,向管理员发出警报。这些产品构成保护Web应用程序的一个重要防御层,当已知现有应用程序存在漏洞,但可用资源却无法修复这些漏洞时,它们特别有用。然而,由于每个Web应用程序都各不相同,这些产品的效用也往往受到限制,其采用的规则也因而趋于一般化。Web应用程序防火墙通常能够确定最明显的攻击,在这种攻击中,攻击者在每一个请求参数中提交标准的攻击字符串。然而,与这种攻击相比,许多攻击往往更加隐蔽,例如修改隐藏表单字段中的账号来访问其他用户的数据,或者提交无序请求以利用应用程序逻辑中存在的缺陷。在这些情况下,攻击者提交的请求可能与善意用户提交的请求完全相同。之所以称为恶意请求,是因为提交请求的环境有所不同。

在任何安全性至关重要的应用程序中,进行实时警报的最有效方法是将其与应用程序的输入确认机制和其他控制方法紧密结合起来。例如,如果认为cookie中包含一组特殊值中的某个值,那么任何违反这种情况的现象即表明该值已被修改,而且应用程序的普通用户无法执行此类修改。同样,如果一名用户修改隐藏表单字段中的账号,以确定另一名用户的账户,这种做法也明确表现出恶意意图。应用程序的主要防御机制应阻止这些攻击,而且,这些保护机制可轻易与应用程序的警报机制进行整合,提供完全自定义的恶意行为警示。因为已经根据应用程序的实际逻辑定制这些检查,如果清楚了解普通用户的操作权限,那么不管任何现有的解决方案多么易于配置,与之相比,它们都能提供更加准确的警报。

2.3.4 应对攻击

除向管理员发出警报外,许多安全性至关重要的应用程序还含有内置机制,以防御潜在恶意用户。

由于应用程序各不相同,现实世界中的许多攻击要求攻击者系统地探查应用程序中存在的漏洞,提交无数包含专门设计的输入请求,以确定其中是否存在各种常见的漏洞。高效的输入确认机制能够把许多这种类型的请求确定为潜在的恶意请求,并阻止这些输入,防止它们给应用程序造成任何不利影响。然而,我们还应意识到,攻击者仍然能够以某种方式避开这些过滤;而且,应用程序确实包含某些实际的漏洞,等待攻击者去发现和利用。从某种意义上说,进行系统性探查的攻击者可能会发现这些缺陷。

有鉴于此,一些应用程序采取自动反应措施阻止攻击者进行这种形式的探查,例如对攻击者提交的请求的响应速度变得越来越慢,或者终止攻击者的会话,要求其重新登录或在继续攻击前执行其他步骤。虽然这些措施无法阻挡最有耐心和决心的攻击者,但能够阻止许多很随意的攻击者,并且为管理员监控此类情况、在必要时采取更加严厉的措施赢得时间。

当然,阻止显而易见的攻击并不如修复应用程序中存在的所有漏洞重要。然而,在现实情况中,即使我们为清除应用程序中的安全缺陷做出了不懈努力,仍然会有一些可供利用的缺陷存在。给攻击者设置更多阻碍是一种有效的深层防御措施,这样做能够降低任何残存的漏洞被发现和利用的可能性。