Skip to content

安全模型

信任边界

边界谁是被信任的
Lumen Worker运维人员(部署者)
Prism身份提供方,完全信任
配置的 Prism 团队owner/co-owner 可管理应用配置与地址
团队成员可正常收发自己的邮件
入站邮件发件方不信任——内容会被净化
邮件中的远程图片服务器不信任——通过代理抓取

认证

  • 会话存储于 KV,Cookie 为 httpOnly; Secure; SameSite=Lax
  • 会话 TTL 跟随 Prism 令牌;授予了 offline_access 时,接近过期时自动用 refresh token 续期。
  • 用户在配置团队中的 角色 会在每次登录时从 Prism 重新读取。 在 Prism 中调整角色,会在该成员下次登录后立即生效。

授权

  • 所有邮箱接口都按 user_id = session.userId 隔离。
  • 管理员接口 (/api/admin/*) 要求 role ∈ { owner, co-owner }
  • 初始化接口 POST /api/init/setup:仅在 “尚未暂存配置” 时开放; 一旦暂存,必须由配置团队的 owner 通过 OAuth 回调来翻转 init:configured
  • WebSocket 升级会拒绝跨源请求,并重新校验会话 Cookie。

入站 HTML 邮件

每封 HTML 邮件入库时都会被净化:

  • 删除 <script><style><iframe><object><embed><form><svg><math><base><meta><link>(标签 + 内容)。
  • 删除所有 on* 事件处理属性。
  • href/src/action 必须匹配 ^(https?:|mailto:|cid:|tel:|#|/)
  • 行内 style 一律丢弃(防止 expression()url(javascript:...)@import 等手法)。
  • <a> 自动加 target=_blank + rel="noopener noreferrer nofollow"
  • <img> 自动加 loading=lazy + referrerpolicy=no-referrer,且 外部 http(s) URL 被改写为图片代理。

净化后的 HTML 在浏览器中以 <iframe sandbox="allow-popups allow-popups-to-escape-sandbox" srcdoc=…> 渲染,并通过 <meta http-equiv="Content-Security-Policy"> 进一步约束。 脚本不会运行,插件不会加载,文档把自身视为独立源(无法读取父页 Cookie)。

出站 HTML

发送的 HTML 由 RFC 822 构造器封装为 multipart/alternative;构造器会:

  • 从所有头部值中剥离 CR/LF。
  • 校验 Message-IDIn-Reply-ToReferences 必须是合法的 <…@…>
  • 校验附件文件名与 MIME。
  • 拒绝非法地址。

图片代理

参见 存储 中的 SSRF 防护清单。

速率与请求体限额

  • 批量 PATCH 接口单次最多 500 个 id。
  • 图片代理:最大 10 MB,8 秒超时,最多 3 跳重定向。
  • 单用户存储配额(管理员可配置)阻止入站发件人或自循环写入造成的成本失控。
  • 写信侧:浏览器侧附件大小限制阻止显然过大的上传。

不在 Lumen 防护范围内

  • 垃圾邮件。请使用 Cloudflare Email Routing 规则与 SPF/Spamhaus 等手段在边缘过滤。
  • 钓鱼。Lumen 原样展示邮件,不会校验 SPF/DKIM/DMARC 结果。
  • 发件人信誉 / DKIM 签名。出站走 Cloudflare Email Sending,共享发件人信誉由 Cloudflare 决定。

报告漏洞

请在 siiway/lumen 仓库提 issue,标题加 [security];或通过 README 中列出的运维联系方式邮件告知。