Email Verification API 集成安全指南:CSRF 与 XSS 注意事项完整清单
【免费下载链接】email-verificationverified autofill项目地址: https://gitcode.com/GitHub_Trending/em/email-verification
在为网站接入Email Verification API时,最先要关注的不是「怎么发验证邮件」,而是两个经典攻击面:CSRF(跨站请求伪造)与XSS(跨站脚本)。Email Verification API 来自 W3C WICG 的email-verification项目,是一套浏览器级协议(EVP,Email Verification Protocol),通过加密签名的Email Verification Token(EVT)证明邮箱归属,用「已验证自动填充」取代传统的邮箱 OTP 流程。本文结合项目规范,讲清楚它内置的防 CSRF 机制和你必须自行防御的 XSS 风险,并给出一份可直接照做的自检清单。
1. 一分钟背景:Email Verification API 是如何工作的
不涉及协议细节,只需要记住三个角色和一行 HTML:
- 验证方(你的网站):在表单里加一个隐藏字段
- 浏览器:全程中介协调,在表单提交前自动填入令牌
- 签发方(邮箱服务商):确认用户处于登录态后签发带签名的 EVT
你唯一的「集成」动作,是在表单里加一个隐藏 input,nonce由服务端生成:
<input type="email" name="email" autocomplete="email"> <input type="hidden" name="token" nonce="<?php generate_nonce() ?>" autocomplete="email-verification-token">完整流程图见 README.md,HTML 扩展的定义见 index.bs。
💡 关键认知:用户看不到令牌,而你的服务器必须能校验令牌。所有安全设计都围绕这两点展开。
2. 内置的 CSRF 防护:四道防线
2.1 第一道:服务端生成的一次性 nonce
nonce必须是服务端生成的密码学强随机值,并且每次页面渲染都唯一(见 index.bs)。这意味着:
- 攻击者截获旧表单原样重放,服务端认不出该 nonce
- 令牌被绑定到「这一次具体的表单渲染」
⚠️ 常见错误:用前端生成或固定值的 nonce——等于防线形同虚设。
2.2 第二道:Key-Binding JWT 锁定目标站点
浏览器拿到 EVT 后,会把网站 origin和nonce一起绑定到令牌中(KB-JWT)。攻击者在别的站点截获的令牌,audience 不匹配会被直接拒绝——这是协议核心的防重放设计,见 index.bs。
2.3 第三道:服务端校验三件套
收到表单后,你的服务器必须完成三项校验(index.bs):
| 校验项 | 防住什么 |
|---|---|
audience与你的 origin 一致 | 令牌被用于其他站点 |
nonce与该表单生成的值一致 | 表单重放 |
exp未过期 | 过期令牌被复用 |
任一校验失败,应回退到传统邮箱 OTP 流程——协议明确要求「优雅降级」而不是直接报错(QUESTIONNAIRE.md)。
2.4 第四道:第三方上下文与跨站请求隔离
- iframe 默认禁用:功能在第三方上下文(如嵌入页面)中不生效,天然堵住 iframe 伪造路径(QUESTIONNAIRE.md)
- 请求指纹:浏览器签发请求携带
Sec-Fetch-Dest: email-verification,签发方可区分合法浏览器请求与脚本伪造(README.md) - Cookie 配置:验证请求在签发方第一方上下文发出,
SameSite=StrictCookie 的泄漏路径需纳入评估,项目已将其列为待决事项(README.md)
3. XSS 攻击面:协议不替你守的部分
3.1 隐藏字段的令牌可以被页面脚本读到
规范自身就提出了这个问题:「是否应该保护nonce与令牌值不被脚本访问?」(README.md)。当前的答案是:不保护。也就是说:
- 站点一旦被 XSS 攻破,攻击者可以读取隐藏字段里已填入的令牌值
- 令牌绑定的是你的origin,同源的攻击者可以正常使用它——等于 XSS 能把一个「未验证访客」变成你眼中的「已验证用户」,绕过邮箱验证建立的信任边界
3.2 为什么攻击者没法直接脚本拿到令牌?
好消息:获取令牌需要用户主动选择邮箱并在浏览器权限弹窗中点击允许,整个流程由浏览器中介完成,网站脚本无法自行触发(index.bs)。所以攻击者唯一的路径,仍然是先注入一段 XSS 脚本。
3.3 三个落地动作
- 转义一切用户输出:邮箱字段是用户输入,反射型 XSS 是经典注入点
- 启用严格 CSP:限制内联与第三方脚本来源,压缩 XSS 入口
- nonce 绑定会话且一次性:用后即废,即使令牌被读到,攻击者也无法完成有效提交
4. Email Verification API 集成安全自检清单 ✅
| # | 检查项 | 类别 |
|---|---|---|
| 1 | nonce服务端生成、随机、每页唯一 | 防 CSRF |
| 2 | 提交时校验 audience、nonce、exp 三项 | 防 CSRF |
| 3 | 校验失败时回退到传统邮箱验证流程 | 可用性 |
| 4 | 敏感操作(改密、大额转账)不要只依赖邮箱验证令牌,需叠加其他认证 | 纵深防御 |
| 5 | 用户输出转义 + 严格 CSP | 防 XSS |
| 6 | nonce 绑定会话、一次性失效 | 防 XSS |
| 7 | iframe / 第三方页面不使用令牌 | 防 CSRF |
⚠️ 第 4 条最容易被忽略:该 API 证明的是「用户登录了邮箱应用」,弱于「邮件确实投递到了他的收件箱」。项目自己在安全注意事项中就把这一点列为已知限制(README.md),高风险场景请叠加二次验证。
5. 快速体验:在 Chrome Canary 中开启功能 🔬
接入自己网站前,可以先按 HOWTO.md 感受完整流程:
- 安装 Chrome Canary
- 打开
chrome://flags/,搜索Email Verification Protocol开启后重启 - 在
chrome://version确认版本 ≥ 145 - 确保
chrome://settings/addresses中有支持 EVP 的域名邮箱,且已登录该域名
6. 项目文件导航 📁
| 文件 | 内容 |
|---|---|
| README.md | 协议提案:背景动机、完整流程、备选方案对比 |
| index.bs | 正式规范:HTML 扩展、浏览器与验证方处理模型、安全与隐私注意事项 |
| HOWTO.md | Chrome Canary 开启与真实网站验证步骤 |
| QUESTIONNAIRE.md | W3C 安全与隐私自审问答,含第一/第三方上下文隔离说明 |
| CONTRIBUTING.md | W3C WICG 贡献指南 |
想深入了解协议在「为什么不用 JavaScript 命令式 API」等设计取舍上的讨论,可阅读 README.md 的 Alternatives Considered 章节。
【免费下载链接】email-verificationverified autofill项目地址: https://gitcode.com/GitHub_Trending/em/email-verification
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考