Cloud Mail 读信补记,远程图片改由服务器去取
记录 Cloud Mail 阅读页隔离脚本、由服务器代取远程图片,以及下载 HTML 附件前去掉可执行内容。
- 8 分钟阅读
- 2026.10.16
阅读页不执行邮件里的脚本。普通远程图片由已登录的服务器代取,读者的网络地址不发给发件人,对方仍可能知道图片被取过。
域名邮箱部署 和 附件验证 写到信能收、附件能下。我接着看的是打开 HTML 邮件的时候。发件人还能不能知道我读过,邮件里的东西还能不能碰到邮箱的登录状态。
2026 年 10 月 16 日,这套阅读处理已经发到线上。域名和邮箱地址仍按前两篇换成 example.com,资源编号和凭据不写在这里。
阅读页和登录状态
邮件正文存在数据库里。打开时再清理一遍,库存的原文不动。清理会拿掉脚本、内嵌框架、事件处理,以及会自己提交的表单。
登录令牌放在浏览器的本地存储里,请求时放进 Authorization 头。读信的那一块如果和邮箱网站算同一个来源,邮件里的代码一旦跑起来,面对的就是邮箱自己,令牌也在旁边。
阅读页因此放进一个隔离框架。框架不允许执行脚本。外层页面仍要量里面的高度,也要把自己生成的图片放进去显示,所以框架和邮箱页面仍算同一个来源。脚本权限不能同时打开。两个一起开,这层隔离会失效,邮件里的代码就回到邮箱网站上。
框架里还有一条内容限制。图片、音视频和字体只接受本页生成的地址,以及直接嵌在页面里的小图。远程样式、远程字体和向外提交都进不来。清理漏掉一个图片地址时,浏览器也不会自己去请求。
我用本机 Chrome 做了一个同样的框架,里面放了脚本、图片加载失败时的处理,还有一张远程小图。脚本没有执行,失败处理没有执行,小图的请求没有发出。外层放进去的本地图片可以显示,宽度是 1。这只核对了框架本身。我没有拿一封真实的恶意邮件在线上点开。
远程图片
追踪像素是一张很小的远程图。浏览器去取它,发件人的服务器就知道这封信被打开了,还能看见取图那一端的网络地址。
默认仍不加载普通远程图片。点“仍然显示”,或者关掉“阻止邮件追踪”,普通图片会出来。早先这一步由浏览器直接访问对方的地址,打开这件事和读者的网络地址会一起交出去。
现在由已经登录的邮箱接口去取。浏览器把图片地址交给自己的网站,网站取回内容,再变成只能在本页使用的地址。发件人看不到读者的网络地址。他仍可能知道有人取过这张图,看见的是 Cloudflare 的地址。
追踪像素不走这条代取。开关开或关,像素、远程样式和远程字体都会去掉。写回复和转发时,引用进编辑器的原文也去掉这些远程内容,免得写信的时候就替对方确认已读。
代取只收公网的 http 和 https 图片。带账号密码的地址、本机、内网,以及 169.254.169.254 这种云主机查询自身信息的地址,都会拒绝。SVG 不收。对方若再跳转到别的地址,最多跟几步,每一步重新检查。单张不超过 5MB,超过 8 秒就停下。接口要求登录。没有登录去调,返回 401。
已登录的人可以用它取公网上的普通图片。私有地址和非图片被挡住了,未登录的人也进不来。这台个人邮箱,我接受这个范围。
链接和回复
有些点击统计把真实网址包在自己的域名里,包得很清楚。读信时会拆开,换成目的地,并不附带来源。拆不开、我又认得的那类追踪域名,链接会直接拿掉,点不了。普通外部链接还在,新窗口打开,同样不附带来源。
名单外面的追踪域名不在这次处理里。那种链接点下去,对方仍可能收到一次访问。
回复我对照过现有发信代码。应用里回复用的是收信时存下来的发件人地址,不改用邮件里另外写的回复地址。这次没有为它改代码。
下载出去的附件
HTML、SVG 和 XML 如果原样下载,再用浏览器打开,阅读页里的清理就管不到。这次在送出文件时处理。桶里和 KV 里的原件不改。
放得进内存的小文件会先去掉脚本和远程追踪,再按附件下载,并告诉浏览器不要把它当能跑脚本的网页。超过 2MB 的不解析,改成普通二进制下载,同样要求不要当网页打开。下载到电脑后再打开,文件已经离开邮箱网站,读不到登录状态。里面若还留着能向外请求的内容,那是下载之后的事,可能通知对方,拿不到邮箱令牌。
按扩展名看是 HTML、对象又找不到时,空内容曾经会被当成一份正常网页返回。找不到的附件现在保持 404。
登录页背景仍走原来的公开路径,不套这套附件处理。
Telegram 里看全文用了同样的隔离框架。那个页面没有登录状态,不能代取图片,远程图片就一直不加载。页面上会写明拦下了多少处。
上线时核对过的结果
反追踪和隐私测试 15 项通过,邮件认领 10 项,存储 10 项,Telegram 通知 21 项。前端生产构建通过。没有重放数据库迁移。
上线后网站返回 HTTP 200。第一次打开首页,边缘缓存还指着上一版脚本。再请求一次、不使用那份旧缓存,页面换成了这次的脚本。未登录访问附件和远程图片接口,都是 401。
账户转发仍把原始邮件原样转出去。改写原文再转发,容易弄丢附件,也会碰到来信的签名,这次没动。用 Resend 发出去的信,如果域名上开着打开统计,那是发信服务自己记的,阅读页的清理管不到。