5.6. 基于 Web 的应用程序输入(特别是 CGI 脚本)

基于 Web 的应用程序(例如 CGI 脚本)运行在一些受信任的服务器上,并且必须通过 Web 以某种方式获取它们的输入数据。由于输入数据通常来自不受信任的用户,因此必须验证这些输入数据。实际上,这些信息可能实际上来自不受信任的第三方;有关更多信息,请参阅第 7.15 节。例如,CGI 脚本通过一组标准环境变量和标准输入传递这些信息。本文的其余部分将专门讨论 CGI,因为它是实现动态 Web 内容最常用的技术,但对于大多数其他动态 Web 内容技术,一般问题是相同的。

另一个额外的复杂之处在于,许多 CGI 输入是以所谓的“URL 编码”格式提供的,也就是说,某些值以 %HH 格式编写,其中 HH 是该字节的十六进制代码。您或您的 CGI 库必须通过 URL 解码输入来正确处理这些输入,然后检查生成的字节值是否可接受。您必须正确处理所有值,包括有问题的值,例如 %00 (NIL) 和 %0A(换行符)。不要多次解码输入,否则诸如“%2500”之类的输入将被错误处理(%25 将被翻译为“%”,并且生成的“%00”将被错误地翻译为 NIL 字符)。

CGI 脚本通常通过在其输入中包含特殊字符来受到攻击;请参阅上面的评论。

Web 应用程序可用的另一种数据形式是“cookies”。同样,用户可以提供任意 cookie 值,因此除非采取特殊预防措施,否则它们是不可信任的。此外,cookies 可以用于跟踪用户,可能侵犯用户隐私。因此,许多用户禁用 cookies,因此如果可能,您的 Web 应用程序应该设计为不需要使用 cookies(但请参阅我稍后关于您必须验证单个用户身份的讨论)。我鼓励您避免或限制使用持久性 cookies(在当前会话之外持续存在的 cookies),因为它们很容易被滥用。实际上,由于担心侵犯用户隐私,美国机构目前被禁止使用持久性 cookies,除非在特殊情况下;请参阅OMB 备忘录 M-00-13(2000 年 6 月 22 日)中的指导。请注意,要使用 cookies,某些浏览器可能会坚持您拥有隐私配置文件(在服务器的根目录中命名为 p3p.xml)。

一些 HTML 表单包含客户端输入检查以防止某些非法值;这些通常使用 Javascript/ECMAscript 或 Java 实现。这种检查对用户可能很有帮助,因为它可以在“立即”发生,而无需任何网络访问。但是,这种输入检查对于安全性是无用的,因为攻击者可以直接将此类“非法”值发送到 Web 服务器,而无需通过检查。甚至不难破坏这一点;您不必编写程序将任意数据发送到 Web 应用程序。一般来说,服务器必须执行所有自己的输入检查(表单数据、cookies 等),因为它们不能信任客户端安全地执行此操作。简而言之,客户端通常不是“可信通道”。有关可信通道的更多信息,请参阅第 7.11 节

Jerry Connolly 在 http://heap.nologin.net/aspsec.html 上提供了一个关于使用 Microsoft 的 Active Server Pages (ASP) 的用户的输入验证的简短讨论。