摘要

  • 1998 年的 RFC 2369 让邮件列表在标头中公布退订路径。若服务器一见到网址被访问便删除订阅,自动扫描器和主动点击的读者就难以区分。
  • 2017 年的 RFC 8058 增加 List-Unsubscribe-Post: List-Unsubscribe=One-Click。有效 DKIM 签名须覆盖该字段和 List-Unsubscribe;接收端未经用户同意不得发送退订 POST。
  • POST 请求只携带规定的键值对,不依靠 Cookie 或 HTTP 授权;发送方不得用 HTTPS 重定向把操作转交别处。IANA 登记了新标头。

一次检查被当成一次投票

先出现的是一个有用的办法。RFC 2369 允许邮件列表把退订地址放在邮件标头里。读者不必在长邮件的页脚里翻找,接收软件也能直接找到出口。List-Unsubscribe 可以包含 HTTPS 网址。1998 年设计的是可发现的路径,不是识别谁在操作的凭据。

邮件安全软件随后也开始读这些路径。RFC 8058 直言,反垃圾邮件软件经常自动获取标头里的资源,用户没有参与。若列表把访问网址视为完成退订,扫描链接就会变成删除订阅。服务器只见到一次网络请求,无法机械地判断它来自人的意愿还是后台检查。收件人可能仅因防护软件履行职责,就从列表上消失。

发送方常用确认页面挡住误操作。扫描器会打开页面,却不会按第二个按钮;真人可以继续。代价是“单击”不再单击。读者为退出一个列表必须再走一步。这不是按钮摆在哪里的问题,而是把一条供软件查看的地址,同时当作改变他人状态的许可。

2017 年把第二个动作写进标头

RFC 8058 保留旧标头,再要求提供单击退订的发送方放入一个 HTTPS 网址和另一个独立标头。后者的值须恰好是 List-Unsubscribe=One-Click。接收端在取得用户同意后,把这个固定键值对作为请求体,向前一个网址发 HTTPS POST。扫描器对网址的普通访问,与这次有意执行的 POST,在协议上有了不同的动词。

发送方还须用有效 DKIM 签名覆盖两个标头,并把它们列在签名的 h= 项中。这样,退订地址和“支持单击操作”的声明一起成为可核验的邮件内容。没有所需签名时,RFC 8058 要求接收端原则上不提供单击退订。签名证明的是发送方声明的完整性,不替读者作决定。

作决定的是读者。RFC 明确禁止接收端未经用户同意便发送 POST,至于界面如何取得同意,留给接收端设计。三方的职责由此分开:列表方公布并签署操作,邮件程序展示并发起操作,读者决定是否离开。后台扫描仍可查看地址,却不应靠“看了一眼”满足改变列表状态的条件。

服务器必须在原地址办完事

POST 请求体只有那个固定键值对,不能依赖 Cookie、HTTP 授权或额外上下文。因此网址本身必须足以识别具体列表和收件人。RFC 建议采用不易伪造的隐晦标识符。发送方若指望浏览器会话补齐身份,接收端发出的规范请求就无法完成退订。

发送方也不得把 POST 重定向到另一个 HTTPS 地址。RFC 指出,历史上重定向的 POST 常常失败,还可能被浏览器变成 GET。若最终操作依赖跳转链,刚刚建立的动词分界会在途中消失。服务端必须在公布的地址处理这次经同意的请求,而不能把关键一步交给不确定的跳转。

RFC 8058 没有改写 RFC 2369 的其他退订网址用法;它新增的是一条明确标记的单击路径。IANA 的邮件标头登记表收录 List-Unsubscribe-Post。登记给信号一个通用名称,实际退订仍要看签名、用户同意、接收端 POST 和发送方端点是否连成一条链。

出口不是一条链接

这次修订的范围很小,责任划分却很硬。发送方掌握签名声明与处理 POST 的服务器;接收方掌握按钮和发请求的时刻;读者掌握离开的决定。自动检测只能检测。任一环节偷换职责,出口便可能成为误退订装置,或成为只能摆着看的按钮。

这三份官方记录说明标准与登记,不显示任何特定邮件服务用了多少次。要证明实际部署,需要有日期的原始邮件、接收端手册和发送方端点日志。RFC 8058 留下的历史事实已经足够具体:互联网让软件轻易打开链接,邮件系统于是必须说明,哪一次打开才算命令。