DKIM 签名被重放(replay)盗用信誉,该怎么发现和缓解?

1 DKIM 签名被重放(replay)盗用信誉,该怎么发现和缓解?
攻击是怎么成立的

RFC 6376 §8.6 直接描述了这类攻击的形态:攻击者通过一个会为其签名的 MTA 发出一封垃圾邮件,借用签名域(例如某个大型知名邮箱服务商)的信誉而非自己的信誉,随后把这封已带有效签名的邮件重新发送给大量目标收件人。

规范同时点明了它为什么有效:收件方看到来自知名域的有效签名,会提高对该邮件的信任度,从而增加其被投递并呈现给用户的可能性。

关键在于理解 DKIM 保证了什么、没保证什么。DKIM 保证的是被签内容自签名以来未被改动,且签名确由持有该私钥的域产生。它没有保证这封邮件是通过哪条路径发出的、发给了谁、发了多少次。重放攻击恰好落在这个缝隙里:邮件确实是那个域签的,内容也确实没改,唯一变化的是投递对象与规模——而这两项都不在签名覆盖范围内。

由此得到一条重要的判定原则:「DKIM 通过」只说明签名有效,不说明这封邮件的发送行为是被签名域授权的。把 DKIM pass 直接等同于「可信」,正是这类攻击得以成功的前提。

为什么常见的两个「解法」都不成立

其一,x= 标签不是反重放手段。这是规范明确写下的。RFC 6376 §3.5 在定义 x=(签名过期)标签时给出了一条提示性说明:「x=」标签的用意并不是作为一种反重放防御

规范对 x= 的完整定义是:它是一个明文无符号十进制整数,为推荐使用的标签,默认无过期;格式与 t= 相同,表示的是绝对日期而非相对签名时间的时间差;若验证方的验证时间已过该过期日期,签名可以被认为无效;验证时间应取该报文首次到达验证方管理域的时间(若该时间可靠可得),否则取当前时间;同时存在时 x= 的值必须大于 t= 的值。

为什么它不能防重放:过期时间是一个时间窗,重放只要发生在窗口内就完全有效。把窗口设得极短会与正常投递延迟、队列重试、离线接收冲突,造成大量合法邮件签名失效。它能限制的只是「很久以后再重放」,而实际重放通常在极短时间内完成。

其二,l= 标签不但不能帮忙,反而引入新风险。RFC 6376 §8.2 指出,使用 l=(正文长度限制)标签可能导致向最终用户展示欺诈性内容而不加适当警示。该标签的本意是提高签名在面对既修改内容又不重新签名的邮件列表时的稳健性,但它使得怀有恶意的中间方可以修改报文、加入只对攻击者有利的内容;追加的内容有可能在收件人眼中完全取代原始内容,并挫败重复报文检测算法。

规范给出的缓解方向及其局限

RFC 6376 §8.6 对缓解手段的表述是审慎的,它称之为部分解决方案,并同时指出了每个方向的代价:

  • 信誉服务:通过信誉服务传达「某个具体邮件地址正被用于发送垃圾邮件、来自该签名方的邮件很可能是垃圾邮件」这一事实。这要求一种实时的检测机制,才能反应得足够快。规范并提醒,此类措施可能被滥用——例如攻击者大量重发从受害者处收到的邮件,使受害者看起来像是垃圾邮件发送者。
  • 大规模验证方的流量观测:规模较大的验证方或许能够察觉短时间内出现异常大量携带同一签名的邮件。这是最贴近重放本质的信号——重放的特征就是同一份签名的高频复用。
  • 协作系统:规模较小的验证方可以通过既有的协作系统获得大体相同数量的信息。

请注意这些方案的共同特点:它们都依赖接收侧的横向观测能力,而不是签名本身能提供的保证。这再次印证了前面的原则——重放利用的是签名覆盖范围之外的维度,因此只能在签名之外解决。

发信方能做的事:把「谁能拿到签名」管起来

对拥有签名域的一方而言,最有效的措施不在验证侧而在签名的准入侧。防止自家域被用作重放的信誉载体,重点在于收紧「什么样的邮件能拿到签名」:

  1. 严格管控可以触发签名的发信路径。任何能让外部输入进入签名流程的入口——开放的提交端点、被盗用的账号凭据、可被滥用的转发或群发功能——都是重放攻击的起点。这一条比后续所有检测措施都更根本。
  2. 对提交侧使用强身份认证。账号失陷是最常见的入口。NIST SP 800-177 Rev. 1《Trustworthy Email》给出了可信邮件部署的系统性建议,可作为整体加固的参考框架。
  3. 不要使用 l= 标签。理由见上一节,它带来的风险远大于收益。
  4. 对被签信头做充分覆盖。签名覆盖的信头字段越充分,攻击者在重放时可改动的余地越小。注意这缓解的是「重放并篡改」,无法缓解「原样重放」。
  5. 为不同用途使用不同的选择器与密钥。把事务邮件、营销邮件、内部通知的签名密钥分开,一旦某一路径被滥用,影响面与处置动作都可以限定在该选择器范围内,必要时可单独轮换或停用。
  6. 监控自家签名的使用广度。把「同一签名值在多少不同接收方处被观测到」纳入观测。DMARC 聚合报告可以提供部分视角——如果报告显示大量本域邮件从预期之外的来源投出且 DKIM 通过,就应当怀疑签名被重放。
接收方能做的事:不要把 DKIM pass 当作终点
  • 把认证结果当作输入,而不是结论。RFC 8601 定义的 Authentication-Results 信头用于记录认证状态,它的价值在于为后续判定提供依据。「DKIM pass 即放行」是错误的策略设计。
  • 关注同一签名的复用广度。这是最贴近重放特征的检测维度:同一个签名值在短时间内命中大量不同收件人。规范提到的正是这一方向。
  • 核对签名域与其他身份的一致性。DMARC 要求身份对齐。若 DKIM 通过的域与信封发件人、与 From 展示给用户的域不一致,本身就是需要额外审视的信号。
  • 关注转发链路。RFC 8617 定义的 ARC 用于在跨中间方的场景下传递认证结果链。它解决的是「合法转发导致认证失败」的问题,不是重放问题,两者不要混淆——但在分析一封邮件的实际路径时,ARC 链提供的中间方信息是有价值的上下文。
  • 把内容与行为信号并入判定。重放邮件的内容在原始上下文中可能完全正常,其异常体现在投递对象与规模上。只看内容的检测天然对这类攻击不敏感,必须补充行为维度。
  • 处置要留证据。判定为重放而拦截时,应记录签名值、签名域、选择器、观测到的接收面,便于向签名域反馈。签名域往往是最后一个知道自己被当作信誉载体的人。

参考:RFC 6376《DomainKeys Identified Mail (DKIM) Signatures》§3.5("t=" 与 "x=" 标签)、§8.2 Misuse of Body Length Limits、§8.6 Replay/Spam Attacks、§8.7,D. Crocker、T. Hansen、M. Kucherawy 编,2011 年 9 月,STD 76,DOI 10.17487/RFC6376,https://www.rfc-editor.org/rfc/rfc6376.html ;RFC 8617《The Authenticated Received Chain (ARC) Protocol》,K. Andersen 等,2019 年 7 月,https://www.rfc-editor.org/rfc/rfc8617.html ;RFC 8601《Message Header Field for Indicating Message Authentication Status》,M. Kucherawy,2019 年 5 月,https://www.rfc-editor.org/rfc/rfc8601.html ;RFC 9989《Domain-Based Message Authentication, Reporting, and Conformance (DMARC)》,2026 年 5 月,https://www.rfc-editor.org/rfc/rfc9989.html ;NIST SP 800-177 Rev. 1《Trustworthy Email》,2019 年 2 月,DOI 10.6028/NIST.SP.800-177r1,https://csrc.nist.gov/pubs/sp/800/177/r1/final