15. 安全注意事项 (Security Considerations)
15 安全注意事项
本节旨在向应用开发者, 信息提供者和用户说明本文档所描述的 HTTP/1.1 在安全方面的局限性. 这里的讨论并未给出这些问题的最终解决方案, 但确实 提出了一些降低安全风险的建议.
15.1 个人信息 (Personal Information)
HTTP 客户端通常掌握大量个人信息, 例如用户名, 所在位置, 邮件地址, 密码, 加密密钥等. 因此, 它们应该 (SHOULD) 非常谨慎, 防止这些信息 通过 HTTP 协议被无意泄露给其他来源. 我们强烈建议为用户提供方便的界面, 使其能够控制此类信息的传播, 并且要求设计者与实现者在这一领域格外小心. 历史表明, 这一方面的错误往往会造成严重的安全和/或隐私问题, 并给实现者 所在公司带来极为不利的舆论影响.
15.1.1 服务器日志信息的滥用 (Abuse of Server Log Information)
服务器能够保存与用户请求相关的个人数据, 而这些数据可能暴露其阅读模式 或感兴趣的主题. 这类信息显然具有机密性质, 并且在某些国家, 其处理方式 可能受法律约束. 通过 HTTP 协议提供数据的人, 有责任确保这类材料在未经 任何可由公开结果识别出的个人许可前, 不会被分发.
15.1.2 敏感信息的传输 (Transfer of Sensitive Information)
与任何通用数据传输协议一样, HTTP 无法规制被传输数据的内容, 也不存在
任何先验方法来判断某一特定信息片段在某个具体请求上下文中的敏感程度.
因此, 应用应该 (SHOULD) 尽可能把对这类信息的控制权交给信息提供者.
在这一背景下, 有四个头字段特别值得注意: Server, Via, Referer
和 From.
公开服务器所运行软件的具体版本, 可能使服务器主机更容易遭受针对已知存在
安全漏洞的软件的攻击. 实现者应该 (SHOULD) 将 Server 头字段做成可配置
选项.
作为网络防火墙入口的代理, 对于那些可标识防火墙后方主机的头部信息传输,
应该 (SHOULD) 采取特别预防措施. 尤其是, 它们应该 (SHOULD) 删除或以
清洗后的版本替换任何在防火墙后方生成的 Via 字段.
Referer 头允许分析用户的阅读模式并推断反向链接. 虽然它可能非常有用,
但如果用户细节没有从 Referer 所包含的信息中剥离, 它的能力就可能被
滥用. 即便个人信息已经被去除, Referer 头仍可能指示某个私有文档的 URI,
而公开该 URI 可能并不恰当.
From 字段中发送的信息可能与用户的隐私利益或其站点的安全策略相冲突,
因此, 在用户无法禁用, 启用和修改该字段内容的情况下, 不应该 (SHOULD NOT)
传输该字段. 用户必须 (MUST) 能够通过用户偏好设置或应用默认配置来设定
此字段内容.
我们建议, 但不强制要求, 为用户提供一个方便的开关界面, 以启用或禁用
From 和 Referer 信息的发送.
User-Agent (第 14.43 节) 或 Server (第 14.38 节) 头字段有时可以
被用来判断某个具体客户端或服务器是否存在可被利用的特定安全漏洞. 遗憾的
是, 同样的信息也常常被用于其他有价值的用途, 而 HTTP 目前还没有更好的
机制来满足这些用途.
15.1.3 在 URI 中编码敏感信息 (Encoding Sensitive Information in URI's)
由于链接来源本身可能是私有信息, 或可能暴露原本私有的信息来源, 因此强烈
建议用户能够选择是否发送 Referer 字段. 例如, 浏览器客户端可以提供一个
用于公开浏览/匿名浏览的切换开关, 以分别启用/禁用 Referer 与 From
信息的发送.
如果引用页面是通过安全协议传输的, 则客户端不应该 (SHOULD NOT) 在
一个非安全的 HTTP 请求中包含 Referer 头字段.
使用 HTTP 协议的服务作者不应该 (SHOULD NOT) 使用基于 GET 的表单提交 敏感数据, 因为这会导致这些数据被编码进 Request-URI. 许多现有服务器, 代理和用户代理都会在某些地方记录请求 URI, 而这些记录可能会被第三方看到. 服务器可以改用基于 POST 的表单提交.
15.1.4 与 Accept 头相关的隐私问题 (Privacy Issues Connected to Accept Headers)
Accept 请求头可能向所有被访问的服务器暴露关于用户的信息. 其中
Accept-Language 头尤其可能泄露用户认为属于私密性质的信息, 因为对特定
语言的理解能力通常与某一特定族群成员身份高度相关.
那些允许配置并在每个请求中发送 Accept-Language 头内容的用户代理,
强烈建议在配置过程中加入提示信息, 让用户意识到这会带来的隐私损失.
一种限制隐私损失的方法是, 用户代理默认省略 Accept-Language 头的发送,
并在检测到服务器生成的某些 Vary 响应头字段表明发送此类头可以提升服务
质量时, 再询问用户是否开始向该服务器发送 Accept-Language 头.
在每个请求中发送复杂的, 高度定制化的 Accept 头字段, 尤其是在其中包含
质量值 (quality values) 时, 可被服务器用作相对可靠且长期有效的用户标识符.
这类标识符能够让内容提供者追踪用户点击轨迹, 也能让协作的内容提供者匹配
跨服务器的点击轨迹或单个用户提交的表单.
需要注意的是, 对于许多未处于代理之后的用户来说, 运行用户代理的主机网络
地址同样会充当长期有效的用户标识符. 在通过代理增强隐私的环境中, 用户代理
在向终端用户提供 Accept 头配置选项时, 应保持克制. 作为一种极端的隐私
防护措施, 代理甚至可以过滤被转发请求中的 Accept 头. 提供高度头字段可
配置能力的通用用户代理, 应该 (SHOULD) 警告用户这可能带来的隐私损失.
15.2 基于文件名和路径名的攻击 (Attacks Based On File and Path Names)
HTTP 源服务器的实现应该 (SHOULD) 小心限制 HTTP 请求返回的文档, 使其 仅限于服务器管理员本来打算提供的那些内容. 如果 HTTP 服务器将 HTTP URI 直接转换为文件系统调用, 则服务器必须 (MUST) 特别注意, 不要提供那些原本 无意传递给 HTTP 客户端的文件.
例如, UNIX, Microsoft Windows 以及其他操作系统都使用 .. 作为路径
组件来表示当前目录之上的一级目录. 在这类系统上, 如果 Request-URI 中的
此类构造会导致访问超出 HTTP 服务器预期可访问范围之外的资源, 则 HTTP
服务器必须 (MUST) 禁止该构造.
类似地, 仅供服务器内部引用的文件, 例如访问控制文件, 配置文件和脚本代码, 也必须 (MUST) 防止被不恰当地获取, 因为它们可能包含敏感信息. 经验表明, 这类 HTTP 服务器实现中的细小缺陷都可能演变成安全风险.
15.3 DNS 欺骗 (DNS Spoofing)
使用 HTTP 的客户端高度依赖 Domain Name Service, 因而通常容易受到基于 IP 地址与 DNS 名称被故意错误关联的安全攻击. 客户端在假定某个 IP 编号与 DNS 名称之间关联关系持续有效时, 需要保持谨慎.
尤其是, HTTP 客户端应该 (SHOULD) 依赖其名称解析器来确认 IP 编号与 DNS 名称之间的关联关系, 而不是缓存先前主机名查找的结果. 许多平台在合适情况 下已经能够本地缓存主机名查找结果, 并且它们应该 (SHOULD) 被配置为这样做. 不过, 这类查找结果只有在名称服务器报告的 TTL (Time To Live) 信息表明 这些缓存信息很可能仍然有用时, 才适合被缓存.
如果 HTTP 客户端为了提高性能而缓存主机名查找结果, 那么它们必须 (MUST) 遵守 DNS 报告的 TTL 信息.
如果 HTTP 客户端不遵守这一规则, 那么当先前访问过的服务器 IP 地址发生 变化时, 它们就可能被欺骗. 由于网络重新编号预计会越来越普遍 [24], 这种 攻击形式出现的可能性也会增加. 因此, 遵守这一要求能够降低这种潜在安全 漏洞.
这一要求还可以改善客户端面对使用相同 DNS 名称的复制服务器时的负载均衡 行为, 并降低用户在访问采用该策略的站点时遭遇失败的可能性.
15.4 Location 头与欺骗 (Location Headers and Spoofing)
如果同一台服务器支持多个彼此并不互信的组织, 那么它必须 (MUST) 检查由
这些组织控制生成的响应中的 Location 与 Content-Location 头字段值,
以确保它们不会试图使那些自己无权控制的资源失效.
15.5 Content-Disposition 相关问题 (Content-Disposition Issues)
HTTP 中经常被实现的 Content-Disposition 头 (见第 19.5.1 节) 源自
RFC 1806 [35], 而 RFC 1806 中包含若干非常严重的安全注意事项.
Content-Disposition 不是 HTTP 标准的一部分, 但由于它被广泛实现,
我们在此记录它的用法及其对实现者的风险. 详情请参见 RFC 2183 [49]
(其更新了 RFC 1806).
15.6 认证凭据与空闲客户端 (Authentication Credentials and Idle Clients)
现有的 HTTP 客户端与用户代理通常会无限期保留认证信息. HTTP/1.1 并未提供让服务器指示客户端丢弃这些已缓存凭据的方法. 这是一个重大的缺陷, 需要通过对 HTTP 的进一步扩展来解决.
凭据缓存可能干扰应用安全模型的场景包括但不限于:
- 客户端长时间处于空闲状态, 之后服务器可能希望促使客户端再次提示用户
输入凭据.
- 应用包含会话终止指示, 例如页面上的 `logout` 或 `commit` 按钮;
在这种情况下, 应用的服务器端 "知道" 客户端已无继续保留这些凭据的
理由.
这一问题目前仍在单独研究中. 针对其中某些方面已经存在若干变通方案, 我们 鼓励采用屏保密码保护, 空闲超时, 以及其他能够缓解该问题内在安全风险的 方法. 特别是, 会缓存凭据的用户代理, 应鼓励其提供一个便于用户访问的机制, 使用户能够在自己控制下丢弃已缓存凭据.
15.7 代理与缓存 (Proxies and Caching)
HTTP 代理在其本质上属于中间人 (man-in-the-middle), 因而天然为中间人 攻击提供了机会. 代理所运行系统一旦被攻破, 就可能导致严重的安全和隐私 问题. 代理可以访问与安全相关的信息, 关于个人用户与组织的个人信息, 以及 属于用户和内容提供者的专有信息. 一旦代理被攻破, 或者在实现和配置时没有 充分考虑安全与隐私问题, 它就可能被用于实施范围广泛的潜在攻击.
代理运营者应像保护任何包含或传输敏感信息的系统那样保护代理所运行的系统. 特别是, 在代理处收集的日志信息通常包含高度敏感的个人信息和/或组织信息. 这些日志信息应被谨慎保护, 并制定和遵循适当的使用准则 (第 15.1.1 节).
具备缓存功能的代理还会带来额外潜在漏洞, 因为缓存内容本身就是恶意利用的 吸引目标. 由于缓存内容会在 HTTP 请求完成后继续保留, 针对缓存的攻击 可能在用户认为这些信息已从网络中消失很久之后仍然泄露信息. 因此, 缓存 内容应被视为敏感信息加以保护.
代理实现者应考虑其设计与编码决策, 以及向代理运营者提供的配置选项 (尤其是默认配置) 所带来的隐私和安全影响.
代理的使用者需要意识到, 代理本身并不比运行它的人更值得信任; HTTP 自身 无法解决这一问题.
在适当情况下, 谨慎使用密码学技术也许足以防御广泛的安全与隐私攻击. 不过, 此类密码学内容超出了 HTTP/1.1 规范的范围.
15.7.1 针对代理的拒绝服务攻击 (Denial of Service Attacks on Proxies)
这类攻击确实存在. 它们很难防御. 相关研究仍在继续. 请保持警惕.