RFC 7103《畸形邮件的安全处理建议》中文导读

诚实披露:本页为 IETF RFC 7103 的中文译介版本。原文由 IETF 发布,依 IETF Trust 条款可自由再制与翻译;本译本由 AI 基于人类权威一手文献(RFC 英文原文)辅助整理生成,非人类原创,亦非逐字全文翻译,仅供学习参考。任何规范性判断以英文原文为准,英文原文见 rfc-editor.org/rfc/rfc7103.txt

摘要

互联网邮件生态长期奉行「宽进严出」的稳健性原则,但过度宽容带来了一个具体的安全后果:同一封畸形邮件,安全过滤模块与最终 MUA 的解析结果可能不同。攻击者正是利用这一解析分歧来绕过检测——过滤器看到的是无害内容,用户看到的却是恶意内容。

RFC 7103 系统梳理了实践中常见的畸形形态(行终止符、地址语法、头字段计数、MIME 结构、正文行长等),并对每一类给出推荐的处置方式,目标是让链路上所有组件对同一封邮件形成一致的理解

1. 引言:本文的目的与非目的

文档开篇即纠正一个常见误读:

"Jon Postel's directive is often interpreted to mean that any deviance from a specification is acceptable."(§1.1)

译:Jon Postel 的准则常被解读为「任何偏离规范的做法都是可以接受的」。

作者指出这种解读走得太远。本文的目的是:在畸形邮件已经存在的现实前提下,给出安全的解释方式;非目的是:本文不修改 RFC 5322 / MIME,不为畸形语法背书,也不鼓励生成方产出畸形内容。

4. 内容不变性(Invariant Content)

如果处理链上的某个模块在转交前「顺手修好了」邮件格式,后续的分析模块看到的就已经不是原件,可能因此漏检;同时滥用举报也会失真——只有在报告中包含与生成时完全一致的原始邮件时,滥用举报系统才能有效运作。

推荐处置:链路上各模块应基于相同的原始内容进行分析;确需传递加工结论时,通过追加 Received 字段或带外通道传递,而不要改动对外呈现的邮件内容。

5. 邮件提交代理(MSA)

畸形邮件的源头相当一部分来自执行标准不严的提交环节。推荐处置:MSA 与中继 MTA 应更严格地强制执行 RFC 5322 与 MIME 规范,从入口处减少畸形邮件的产生——这比在收件侧做无穷补救更有效。

6. 行终止符

异常:非合规实现产出仅 LF 或孤立 CR 的行终止;严格按标准解析时,整封邮件会被当成「一行」,头体结构随之崩塌。

"Thus, it will typically be safe and helpful to treat an isolated CR or LF as equivalent to a CRLF when parsing a message."(§6)

译:因此在解析邮件时,把孤立的 CR 或 LF 视作等同于 CRLF,通常既安全又有帮助。

注意适用范围:该建议针对原始 SMTP 数据,不适用于已解码的 MIME 实体内部。

7. 头部异常

7.1 废弃与无效语法的转换

异常:地址字段使用废弃或非法语法,攻击者可借此让过滤器与 MUA 提取出不同的地址。总原则:应当拒收;若无法拒收,则按语义在内部转换为合规形式。原文给出的具体形态与安全解释包括:

子节异常形态推荐的安全解释
7.1.1废弃的源路由语法(主机-地址形式)只保留真实的目标地址,丢弃源路由部分
7.1.2地址被多层尖括号包裹归一为单层尖括号
7.1.3尖括号不平衡(缺左或缺右)补齐或去除多余括号后取出地址
7.1.4圆括号不平衡补全为注释或显示名,并明确提取有效地址
7.1.5地址列表中逗号位置错误(逗号落在尖括号内)解释为两个独立地址
7.1.6引号不平衡取最合理解释,补齐引号形成「显示名 + 地址」
7.1.7裸 local-part(只有用户名或只有显示名,无完整地址)提交代理应拒绝或补全 @主机名;接收方可为内部评估合成一个有效地址

7.2 非头部行

异常:头部区域内出现既非合法头字段、又未以空白开头缩进的行。不同实现对「头/体分界在哪」的判断会出现分歧,这是典型的绕过入口。推荐处置:若不采取拒收策略,则向前搜索空行或下一个合法头字段,把该异常行当作折叠续行并入前一字段。

7.3 异常空格

异常:头字段续行中夹入「仅含空白字符」的行,可能被某些实现误判为头体分隔空行。推荐处置:解析时忽略该行;生成邮件时直接移除。

7.4 头部畸形

异常:字段名与冒号之间插入多余空格(如 MIME-Version : 1.0)。虽然旧语法曾允许,但当前共识是移除冒号前的空白并以修正后的形式发出。

7.5 头字段计数

异常:RFC 5322 对某些字段的出现次数有限制,但实践中鲜有强制执行;重复或缺失字段可被用于欺骗(例如两个 From,过滤器看第一个、MUA 显示第二个)。可选处置:拒收、移除超额实例、合并同类字段,或将超额实例重命名(如加 BAD- 前缀)后保留以便取证。

7.6 缺失或错误的字符集信息

异常:文本类 MIME 实体常常缺失或误标 charset;内容中夹带的空字节(NUL)可用于截断解析、隐藏恶意内容。推荐处置:以启发式方式判定字符集,或直接拒绝处理;对孤立的空字节静默丢弃,对大量空字节则拒绝处理。

7.7 八位数据

异常:在未协商相应扩展的情况下,邮件实体或头字段中出现非 ASCII 的八位数据。推荐处置:实体内容按实际已使用的扩展处理;头字段中的八位数据可转换为 encoded-words,或移除/替换;若出现在地址中,则应排除该地址或按 EAI(邮件地址国际化)体系处理。

8. MIME 异常

9. 正文异常

9.1 超长行:单行超过 998 字符(不含终止符)。部分组件会截断后再分析,超出部分即成为藏匿恶意内容的空间。推荐处置:拒收;或在不改变语义的位置断行;或用 MIME 编码重写,使其在传输中断行、解码后复原。

10. 安全考量

本文档的正文本身即为一份安全考量清单——其中部分攻击面此前未被既有规范覆盖。作者强调,这些实践的目的在于缓解已经存在的风险,而非引入新的风险;实现者在采纳「宽容解释」建议时,务必确保自己的解释与下游 MUA 的解释保持一致,否则宽容反而会制造新的分歧。

参考链接