Skip to content

v5.3.2

Latest

Choose a tag to compare

@iding2959 iding2959 released this 29 Oct 09:21
· 0 commits to 5c453fdc79d43632f5ee5a0a4647c22fe8f03a0c since this release

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:

  1. 已绑定当前用户 → 直接幂等返回成功
  2. 否则用条件插入原子抢占:
    INSERT INTO user_mailboxes (user_id, mailbox_id) SELECT ?, ? WHERE NOT EXISTS (SELECT 1 FROM user_mailboxes WHERE mailbox_id = ?)
  3. 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 版本历史表。