虽然我们不可能或无法完全阻止泄露对攻击者有用的信息,但可以采取各种相对简单的措施,最大限度地减少信息泄露,防止将最敏感的数据泄露给攻击者,避免应用程序的安全造成严重破坏。
应禁止应用程序向用户的浏览器返回详尽的错误消息或调试信息。如果发生无法预料的错误(如数据库查询错误、磁盘文件读取故障或外部API调用异常),应用程序应返回相同的常规消息,通知用户出现错误。如果因为支持或诊断目的而有必要记录调试信息,那么将这些信息保存在一个用户无法公开访问的服务器端日志中,并在必要时向用户返回相关日志记录的索引号,方便他们在联系服务台时报告这个错误。
可以配置大多数应用程序平台与Web服务器,使其拦截错误消息,不将它返回给浏览器。
在ASP.NET中,可以使用Web.config文件的customErrors元素,通过设置mode属性为On或 RemoteOnly,并在defaultRedirect节点指定一个定制错误页面,从而阻止详尽的错误消息。
在Java Platform中,可以使用web.xml文件的error-page元素配置定制错误消息。exception-type节点可用于指定一个 Java 异常类型,或者使用error-code节点指定一个HTTP状态码;使用location节点可设定发生错误时显示的定制页面。
在Microsoft IIS中,可以使用一个Web站点属性页面的“定制错误”(Custom Errors)选项卡,为不同的HTTP状态码指定定制错误页面。如有必要,可在每个目录的基础上为每个状态码设置一个不同的定制页面。
在Apache 中,可以使用httpd.conf中的ErrorDocument指令配置定制错误页面。例如:
只要有可能,应禁止应用程序公布对攻击者有用的信息,包括用户名、日志记录或用户个人 资料。如果某些用户需要访问这些信息,应使用访问控制对它们进行有效保护,并且只有在完全必要时才提供这些信息。
如果必须向授权用户透露敏感信息(例如,以便用户更新他们的账户信息),那么在不必要时也不得披露现有数据。例如,应以截短的形式显示保存的信用卡号,绝不能预先填写密码字段,即使它在屏幕上隐藏显示。这些防御措施有助于减轻验证、会话管理与访问控制等应用程序核心安全机制中存在的严重漏洞造成的影响。
只要有可能,应删除或修改服务旗标,避免泄露特定软件版本等信息。执行这种防御所需的步骤依应用程序所使用的技术而定。例如,在Microsoft IIS中,可以使用IISLockDown工具中的URLScan删除Server消息头。在最新版本的Apache 中,使用mod_headers模块可达到相同的目的。由于这些信息会随时改变,建议在进行任何修改之前查阅服务器上的文档资料。
另外,还应删除部署在当前生产环境中的客户端代码(包括全部HTML与 JavaScript 代码)中的所有注释。
还要特别注意任何厚客户端组件,如 Java applet 和 ActiveX 控件。不得在这些组件中包含任何敏感信息。技术熟练的攻击者能够破译或逆向制造这些组件,恢复它们的源代码(请参阅第 5章了解相关内容)。