跳到主要内容

8. Security_Considerations

8.1. 概述 (Overview)

Cookie 存在许多安全陷阱. 本节概述其中一些较为突出的安全问题.

尤其是, Cookie 鼓励开发者依赖环境权限 (ambient authority) 来进行认证, 因而常常容易受到跨站请求伪造 (cross-site request forgery) [CSRF] 等攻击. 此外, 在 Cookie 中存储会话标识符 (session identifier) 时, 开发者也常常会制造会话固定 (session fixation) 漏洞.

传输层加密 (transport-layer encryption), 例如 HTTPS 所使用的加密, 不足以防止网络攻击者获取或篡改受害者的 Cookie, 因为 Cookie 协议本身存在多种漏洞 (见下文的 "弱保密性" 和 "弱完整性"). 此外, 默认情况下, 即使与 HTTPS 结合使用, Cookie 也不会针对网络攻击者提供保密性或完整性.

8.2. 环境权限 (Ambient Authority)

使用 Cookie 对用户进行认证的服务器可能存在安全漏洞, 因为某些用户代理 (user agent) 允许远程方从该用户代理发出 HTTP 请求 (例如通过 HTTP 重定向或 HTML 表单). 发出这些请求时, 即使远程方不知道 Cookie 的内容, 用户代理也会附加 Cookie, 这可能让远程方在缺乏防备的服务器上行使权限.

尽管这一安全问题有许多名称 (例如跨站请求伪造, confused deputy), 但其根源在于 Cookie 是一种环境权限形式. Cookie 鼓励服务器运营者将指定 (以 URL 形式) 与授权 (以 Cookie 形式) 分离. 因此, 用户代理可能会为攻击者指定的资源提供授权, 从而可能导致服务器或其客户端执行攻击者指定的操作, 就好像这些操作已经获得用户授权一样.

服务器运营者可以考虑不使用 Cookie 进行授权, 而是通过将 URL 视为能力 (capability) 来绑定指定与授权. 这种方法不是把秘密存储在 Cookie 中, 而是把秘密存储在 URL 中, 要求远程实体自己提供该秘密. 尽管这种方法并非万灵药, 但审慎应用这些原则可以带来更稳健的安全性.

8.3. 明文 (Clear Text)

除非通过安全信道 (例如 TLS) 发送, Cookie 和 Set-Cookie 头部中的信息都会以明文传输.

  1. 所有敏感信息都在 Cookie 和 Set-Cookie 头部中暴露给窃听者.

  2. 恶意中间方可能会篡改 Cookie 和 Set-Cookie 头部, 在任一方向上进行修改, 造成不可预测的结果.

  3. 恶意客户端可能会在传输前篡改 Cookie 头部, 造成不可预测的结果.

服务器在向用户代理传输 Cookie 时, 应当 (SHOULD) 加密并签名 Cookie 的内容 (使用服务器希望采用的任何格式), 即使这些 Cookie 是通过安全信道发送的. 但是, 加密并签名 Cookie 内容并不能防止攻击者把 Cookie 从一个用户代理移植到另一个用户代理, 也不能防止攻击者稍后重放该 Cookie.

除了加密并签名每个 Cookie 的内容外, 需要更高安全级别的服务器应当 (SHOULD) 仅通过安全信道使用 Cookie 和 Set-Cookie 头部. 通过安全信道使用 Cookie 时, 服务器应当 (SHOULD) 为每个 Cookie 设置 Secure 属性 (见第 4.1.2.5 节). 如果服务器没有设置 Secure 属性, 安全信道提供的保护将在很大程度上失去意义.

例如, 考虑一个在 Cookie 中存储会话标识符, 并且通常通过 HTTPS 访问的 Webmail 服务器. 如果该服务器没有在其 Cookie 上设置 Secure 属性, 主动网络攻击者可以拦截来自用户代理的任意出站 HTTP 请求, 并通过 HTTP 将该请求重定向到 Webmail 服务器. 即使该 Webmail 服务器并未监听 HTTP 连接, 用户代理仍会在请求中包含 Cookie. 主动网络攻击者可以截获这些 Cookie, 将其重放给服务器, 并获知用户电子邮件的内容. 相反, 如果服务器已在其 Cookie 上设置 Secure 属性, 用户代理就不会在明文请求中包含这些 Cookie.

8.4. 会话标识符 (Session Identifiers)

服务器通常不会直接在 Cookie 中存储会话信息 (因为这些信息可能暴露给攻击者或被攻击者重放), 而是在 Cookie 中存储随机数 (nonce, 或 "会话标识符"). 当服务器收到带有随机数的 HTTP 请求时, 可以把该随机数作为键来查找与该 Cookie 关联的状态信息.

使用会话标识符 Cookie 可以限制攻击者在获知 Cookie 内容后造成的损害, 因为该随机数只对与服务器交互有用 (不同于非随机数的 Cookie 内容, 后者本身可能是敏感信息). 此外, 使用单个随机数可以防止攻击者把与服务器两次交互中的 Cookie 内容 "拼接" 在一起, 否则可能导致服务器出现意外行为.

使用会话标识符并非没有风险. 例如, 服务器应当 (SHOULD) 注意避免 "会话固定" 漏洞. 会话固定攻击分三步进行. 首先, 攻击者把一个会话标识符从自己的用户代理移植到受害者的用户代理. 其次, 受害者使用该会话标识符与服务器交互, 这可能把用户的凭据或机密信息赋予该会话标识符. 第三, 攻击者使用该会话标识符直接与服务器交互, 从而可能获得用户的权限或机密信息.

8.5. 弱保密性 (Weak Confidentiality)

Cookie 不按端口提供隔离. 如果运行在某个端口上的服务可以读取某个 Cookie, 则运行在同一服务器另一个端口上的服务也可以读取该 Cookie. 如果运行在某个端口上的服务可以写入某个 Cookie, 则运行在同一服务器另一个端口上的服务也可以写入该 Cookie. 因此, 服务器不应 (SHOULD NOT) 在同一主机的不同端口上同时运行互不信任的服务, 并使用 Cookie 存储安全敏感信息.

Cookie 不按方案 (scheme) 提供隔离. 虽然 Cookie 最常与 http 和 https 方案一起使用, 但给定主机的 Cookie 也可能可供其他方案使用, 例如 ftp 和 gopher. 这种缺乏方案隔离的问题在允许访问 Cookie 的非 HTTP API 中最为明显 (例如 HTML 的 document.cookie API), 但方案隔离的缺失实际上也存在于处理 Cookie 本身的要求中 (例如, 考虑通过 HTTP 检索采用 gopher 方案的 URI).

Cookie 并不总是按路径提供隔离. 尽管网络层协议不会把为一个路径存储的 Cookie 发送到另一个路径, 但某些用户代理会通过非 HTTP API 暴露 Cookie, 例如 HTML 的 document.cookie API. 由于其中一些用户代理 (例如 Web 浏览器) 不隔离从不同路径接收的资源, 从一个路径检索到的资源可能能够访问为另一个路径存储的 Cookie.

8.6. 弱完整性 (Weak Integrity)

Cookie 不为同级域 (及其子域) 提供完整性保证. 例如, 考虑 foo.example.com 和 bar.example.com. foo.example.com 服务器可以设置一个 Domain 属性为 "example.com" 的 Cookie (可能覆盖 bar.example.com 已设置的现有 "example.com" Cookie), 用户代理随后会在发往 bar.example.com 的 HTTP 请求中包含该 Cookie. 在最坏情况下, bar.example.com 将无法区分这个 Cookie 和它自己设置的 Cookie. foo.example.com 服务器可能利用这种能力对 bar.example.com 发起攻击.

即使 Set-Cookie 头部支持 Path 属性, Path 属性也不提供任何完整性保护, 因为用户代理会接受 Set-Cookie 头部中的任意 Path 属性. 例如, 对 http://example.com/foo/bar 请求的 HTTP 响应可以设置一个 Path 属性为 "/qux" 的 Cookie. 因此, 服务器不应 (SHOULD NOT) 在同一主机的不同路径上同时运行互不信任的服务, 并使用 Cookie 存储安全敏感信息.

主动网络攻击者还可以冒充来自 http://example.com/ 的响应并注入 Set-Cookie 头部, 从而向发送到 https://example.com/ 的 Cookie 头部中注入 Cookie. example.com 上的 HTTPS 服务器将无法区分这些 Cookie 和它自己在 HTTPS 响应中设置的 Cookie. 即使 example.com 只使用 HTTPS, 主动网络攻击者也可能利用这种能力对 example.com 发起攻击.

服务器可以通过加密并签名 Cookie 内容来部分缓解这些攻击. 但是, 使用密码学并不能完全缓解该问题, 因为攻击者可以在用户的会话中重放其从真实 example.com 服务器收到的 Cookie, 造成不可预测的结果.

最后, 攻击者可能通过存储大量 Cookie 来迫使用户代理删除 Cookie. 一旦用户代理达到其存储限制, 用户代理将被迫逐出某些 Cookie. 服务器不应 (SHOULD NOT) 依赖用户代理保留 Cookie.

8.7. 对 DNS 的依赖 (Reliance on DNS)

Cookie 的安全性依赖域名系统 (Domain Name System, DNS). 如果 DNS 部分或完全遭到破坏, Cookie 协议可能无法提供应用程序所需的安全属性.