Repository navigation
V5.3.2 更新说明
发布日期:2026-10-29
安全修复版本,修复 issue #73 报告的
跨用户邮箱接管漏洞。无新增功能,建议所有向普通用户开放账号的部署尽快升级。
主要变更
1. 修复邮箱认领越权(CWE-639 / CWE-284)
POST /api/create 接受任意 local 并调用 assignMailboxToUser,后者经
getOrCreateMailboxId 复用已存在的邮箱行后,直接执行
INSERT OR IGNORE INTO user_mailboxes,未校验该邮箱是否已归属其他用户。
由于 user_mailboxes 只有 UNIQUE(user_id, mailbox_id),同一邮箱可以被两个不同
用户各插入一行;而读取邮件、下载 EML、删除、清空、转发、收藏全部以这行关联做权限
判定,因此任意已登录普通用户只要知道地址,就能「认领」他人邮箱,随后读取其邮件
(含验证码/重置链接)、改写 forward_to 长期劫持、清空收件箱。
修复后的 assignMailboxToUser:
- 已绑定当前用户 → 直接幂等返回成功
- 否则用条件插入原子抢占:
INSERT INTO user_mailboxes (user_id, mailbox_id) SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM user_mailboxes WHERE mailbox_id = ?) meta.changes = 0即判定该邮箱已被他人占用,返回 400「该邮箱已被其他用户占用」
采用条件插入而非「先查后插」,避免两个用户并发认领同一地址时双方都通过校验。
2. 行为变化
| 场景 | V5.3.1 及以前 | V5.3.2 |
|---|---|---|
| 普通用户认领已被他人占用的地址 | 静默成功(越权) | 400「该邮箱已被其他用户占用」 |
| 管理员把已分配给 A 的邮箱直接分配给 B | 静默变成多方共有 | 失败,需先 POST /api/users/unassign |
| 重复创建自己已拥有的邮箱 | 成功 | 成功(幂等,行为不变) |
/api/generate 随机生成、创建全新地址 |
成功 | 成功(行为不变) |
兼容性
- DB schema 无变化,无需迁移;升级方式:拉代码 →
wrangler deploy - 单人自用部署没有可利用路径,但建议一并升级
升级后自检
-- 历史上是否已出现同一邮箱被多个用户拥有(结果非空需人工确认归属)
SELECT m.address, COUNT(*) AS owners, GROUP_CONCAT(um.user_id) AS user_ids
FROM user_mailboxes um
JOIN mailboxes m ON m.id = um.mailbox_id
GROUP BY um.mailbox_id
HAVING owners > 1;致谢
漏洞由 @hieuPenguinnn 报告。
历史版本见 README.md 版本历史表。