跳到主要内容

11. 安全考虑

本节分析该协议可能面临的威胁. 其目的是告知协议和应用开发者本文档所描述的 CoAP 的安全限制. 由于 CoAP 实现了 HTTP/1.1 功能的一个子集, [RFC2616] Section 15 中的安全考虑也与 CoAP 相关. 本节集中描述 CoAP 特有的限制.

11.1. 协议解析和 URI 处理​

面向网络的应用可能在其传入分组处理逻辑中暴露漏洞. 复杂解析器是此类漏洞的常见来源, 例如可被远程触发导致节点崩溃, 甚至在节点上远程执行任意代码. CoAP 试图通过降低解析器复杂度, 尽可能为整个可编码值范围赋予含义, 并主动减少由同一含义的多种表示之间不必要选择所造成的复杂度, 来缩小引入此类漏洞的机会. 大部分 URI 处理已移至客户端, 进一步减少了服务器中引入漏洞的机会.

即便如此, CoAP 实现中的 URI 处理代码仍可能是剩余漏洞的重要来源, 应特别谨慎实现. CoAP 访问控制实现需要确保, 从 URI 推导访问控制决策的代码与最终提供该 URI 所寻址资源的代码之间不会因差异而引入漏洞. 剩下最复杂的解析器可能是 CoRE Link Format 的解析器, 尽管该格式的设计目标同样包括降低实现复杂度 [RFC6690]. (另见 [RFC2616] Section 15.2.)

11.2. 代理和缓存​

如 [RFC2616] Section 15.7 所述, 代理本质上是 man-in-the-middle, 会打破直接 CoAP 报文交换可能具有的任何 IPsec 或 DTLS 保护. 因此, 它们是破坏 CoAP 报文交换机密性或完整性的有吸引力目标. 如 [RFC2616] 所指出, 它们也是破坏可用性的有吸引力目标.

当代理还进行缓存时, 对 request/response 数据机密性和完整性的威胁会被放大. 注意, CoAP 未定义 HTTP/1.1 为更好保护敏感数据而提供的任何用于抑制缓存的 Cache-Control options.

对于缓存实现, 适用于发起生成缓存条目的请求的任何访问控制考虑, 也需要适用于缓存中的值. 这既与实现多个安全域的客户端相关, 也与可能服务多个客户端的代理相关. 此外, caching proxy MUST NOT 让具有较低 transport-security 属性的请求访问缓存值, 低于代理首先执行请求转发时所要求的属性.

与 "coap" scheme 不同, 对 "coaps" 标识请求的响应绝不是 "public", 因而 MUST NOT 被复用于共享缓存, 除非缓存能够作出与产生该缓存条目的访问控制决策等价的决策. 但是, 如果该报文在 CoAP 中默认可缓存, 它们可以在 private cache 中复用.

最后, 将 Separate Responses (而非 piggybacked Responses) 分发给多个原始请求者的代理可能提供额外放大 (见 Section 11.3).

11.3. 放大风险​

CoAP 服务器通常以一个响应分组回复一个请求分组. 该响应分组可能显著大于请求分组. 攻击者可能利用 CoAP 节点把一个小攻击分组转换成更大的攻击分组, 这种方法称为 amplification. 因此, CoAP 节点有可能因协议的放大特性而卷入 denial-of-service (DoS) 攻击: 试图使受害者过载但自身可生成流量有限的攻击者, 可以利用放大生成更多流量.

这在启用 NoSec 访问, 可被攻击者访问, 且能够访问潜在受害者 (例如在通用 Internet 上) 的节点中尤其成问题, 因为 UDP 协议无法验证请求分组中给出的源地址. 攻击者只需在合适请求分组的源地址中放入受害者的 IP 地址, 即可生成一个指向受害者的更大分组.

作为缓解因素, 许多受限网络只能生成少量流量, 这可能使 CoAP 节点对这种攻击不那么有吸引力. 但是, 受限网络容量有限也使网络本身容易成为 amplification attack 的受害者.

因此, 如果请求未经过认证, 响应中 SHOULD NOT 提供较大的放大系数. CoAP 服务器可以通过使用 CoAP 的 slicing/blocking modes [BLOCK], 并仅以相对较小的 slices 提供大型资源表示, 来减少它向攻击者提供的放大量. 例如, 对于 1000-byte 资源, 一个 10-byte 请求可能产生 80-byte 响应 (带 64-byte block), 而不是 1016-byte 响应, 从而显著降低所提供的放大.

CoAP 还支持在请求中使用组播 IP 地址, 这是 M2M 的重要要求. Multicast CoAP 请求可能成为意外或蓄意 DoS 攻击的来源, 尤其是在受限网络上. 本规范试图通过限制何时返回响应来降低组播请求的放大效应. 为限制恶意使用的可能性, CoAP 服务器 SHOULD NOT 接受无法以某种方式认证的组播请求, 无论是通过密码学方式, 还是通过某种限制潜在来源的组播边界. 如果可能, CoAP 服务器 SHOULD 将对组播请求的支持限制到确实需要该功能的特定资源.

在某些提供 POSIX-style API [IEEE1003.1] 的通用操作系统上, 判断收到的分组是否寻址到组播地址并不直接. 虽然许多实现会知道自己是否加入了某个组播组, 但这会给寻址到 FF0x::1 形式组播地址的分组带来问题, 因为每个 IPv6 节点都会收到这些分组. 实现 SHOULD 在可用时使用 IPV6_RECVPKTINFO [RFC3542] 这样的现代 API 来作出判断.

11.4. IP 地址欺骗攻击​

由于 UDP 缺少握手, 一个可以自由读取和写入受限网络所承载报文的恶意端点 (即 NoSec 或 nodes/key ratio > 1:1 的 PreSharedKey 部署), 很容易攻击单个端点, 一组端点, 乃至整个网络, 例如通过:

  1. 伪造针对 Confirmable message 或 Non-confirmable message 的 Reset message, 从而使端点 "失聪".

  2. 伪造针对 CON message 的 ACK, 从而可能阻止 CON message 的发送方重传, 并淹没实际响应.

  3. 使用伪造的 payload/options 伪造整个响应 (其影响程度不同: 从扰乱单个响应, 到对支撑基础设施进行更大胆的攻击, 例如污染代理缓存, 或欺骗 resource directory 中的验证/查找接口. 更一般地说, 任何存储全局网络状态并使用 CoAP 作为报文设施来处理状态设置或更新的组件都是潜在目标).

  4. 为目标节点伪造组播请求. 这可能导致网络拥塞/崩溃, 对受害者的 DoS 攻击, 或强制唤醒睡眠节点.

  5. 伪造 observe 报文等.

即使没有传输层安全性, 也可以通过在请求中选择非平凡的随机 token (Section 5.3.1) 来检测并缓解 off-path 攻击者的响应欺骗. [RFC4086] 讨论了安全随机性的要求.

原则上, CoAP 只有在使用 Confirmable message 语义时才能检测其他类型的欺骗, 因为会从受骗端点收到意外的 Acknowledgement 或 Reset messages. 但这要求跟踪已使用的 Message IDs, 并不总是可行, 而且检测通常在损害已经发生后才可用. 这类攻击可以通过使用 NoSec 以外的 security modes 来防止.

无论是否进行源地址欺骗, 客户端都可以通过向服务器发送请求, 最好是复杂请求, 来试图使服务器过载. 地址欺骗使追踪和阻断此类攻击更加困难. 鉴于 CON 请求的成本很小, 这种攻击很容易执行. 在这种攻击下, 总可用能量有限的受限节点可能比计划更快耗尽能量 (battery depletion attack). 此外, 如果客户端使用 Confirmable message, 而服务器以 Confirmable separate response 响应一个 (可能被欺骗的) 且不回应的地址, 服务器将不得不为每个响应分配缓冲区和重传逻辑, 直到 MAX_TRANSMIT_SPAN 耗尽, 这会使其更可能耗尽用于处理合法流量的资源. 后一个问题可以通过 Section 4.7 中讨论的响应速率限制稍加缓解. 攻击者还可能伪造合法客户端的地址. 如果服务器使用 separate responses, 这可能因 NSTART=1 而导致服务器阻塞对该客户端的合法响应. 所有这些攻击都可以通过使用 NoSec 以外的 security mode 来防止, 从而只剩下针对安全协议本身的攻击.

11.5. 跨协议攻击​

诱使 CoAP 端点向伪造源地址发送分组的能力, 不仅可用于放大, 还可用于针对在给定地址 (IP 地址和端口) 监听 UDP 分组的受害者进行 cross-protocol attacks. 其过程如下:

o 攻击者向 CoAP 端点发送一个报文, 并把给定地址作为伪造源地址.

o CoAP 端点向该给定源地址回复一个报文.

o 给定地址处的受害者收到一个 UDP 分组, 并按照另一种协议的规则解释它.

这可用于绕过防火墙规则: 这些规则阻止攻击者与受害者直接通信, 但碰巧允许 CoAP 端点 (它也可能在另一协议中承担有效角色) 与受害者通信.

此外, CoAP 端点也可能成为通过另一种基于 UDP 的协议 (例如 DNS) 的端点生成的 cross-protocol attack 的受害者. 在两种情况下, 如果端点的安全属性依赖于检查 IP 地址 (并用防火墙隔离从外部用伪造 IP 地址发送的直接攻击), 攻击就是可能的. 一般而言, 由于缺少上下文, 基于 UDP 的协议相对容易成为 cross-protocol attacks 的目标.

最后, 通过其他方式传输的 CoAP URIs 可能被用来诱使客户端向其他协议的端点发送报文.

缓解 cross-protocol attacks 的一种方式是严格检查收到分组的语法, 并结合足够不同的语法. 例如, 如果难以诱使 DNS 服务器发送一个能够通过 CoAP 端点检查的 DNS 响应, 这会有所帮助. 遗憾的是, DNS 回复的前两个字节是可由攻击者选择的 ID, 并且会映射到 CoAP header 的重要部分. 接下来的两个字节随后被解释为 CoAP 的 Message ID (即任何值都可接受). DNS count words 可能被解释为 (不存在但 elective 的) CoAP option 0 的多个实例, 或可能被解释为 Token. 最后, 回显的查询可能由攻击者构造, 以在 CoAP 端点上达到预期效果. 服务器添加的响应 (如果有) 随后可能仅被解释为附加 payload.

                               1  1  1  1  1  1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | T, TKL, code +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | Message ID +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | (options 0) +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | (options 0) +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | (options 0) +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | (options 0) +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

 Figure 15: DNS Header ([RFC1035], Section 4.1.1) vs. CoAP Message

一般而言, 对任意一对协议, 其中一个协议完全可能被设计成让攻击者能够导致生成看起来像另一协议报文的回复. 确保或证明不存在可行攻击, 往往比生成尚未完全形成攻击但可能被更有创造力的人进一步发展的示例困难得多. 因此, 只有当端点不只是基于信任分组源 IP 地址来授权攻击者想要的动作时, cross-protocol attacks 才能被完全缓解. 反过来, 一个完全依赖防火墙来保障 CoAP 安全的 NoSec 环境, 不仅需要用防火墙隔离 CoAP 端点, 也需要隔离所有其他可能被诱使通过某种其他基于 UDP 的协议向 CoAP 端点发送 UDP 报文的端点.

除上述考虑外, DTLS 关于 cross-protocol attacks 的安全考虑同样适用. 例如, 如果同一个 DTLS security association ("connection") 被用于承载多种协议的数据, DTLS 就不再提供针对这些协议之间 cross-protocol attacks 的保护.

11.6. 受限节点考虑​

受限节点上的实现者经常发现自己没有良好的熵源 [RFC4086]. 如果情况如此, 该节点 MUST NOT 用于需要良好熵的过程, 例如密钥生成. 相反, 密钥应在外部生成, 并在制造或 commissioning 期间加入设备.

由于处理能力较低, 受限节点特别容易受到 timing attacks. 实现密码学原语时必须特别谨慎.

大量受限节点将被安装在暴露环境中, 对篡改的抵抗力很弱, 包括 keying materials 被恢复. 在定义分配给它们的 credentials 范围时需要考虑这一点. 特别是, 为一组节点分配共享密钥可能会使任何单个受限节点成为颠覆整个组的目标.