摘要

  • 2026 年 8 月发布的 RFC 10017 是 IETF 最佳当前实践。它强烈建议商业、敏感及处理个人数据的浏览器应用采用 Backend for Frontend,让访问和刷新令牌不进入浏览器代码。
  • BFF 能消除多类令牌窃取和新令牌获取路径,却不能隔离与合法应用共享 origin 的恶意代码。没有秘密外泄,只能证明保管边界守住了,不能证明没有未授权动作。

没有令牌失窃的事件

开篇是依据标准威胁模型构造的分析场景,不是真实事故。它迫使调查者把两个经常混合的问题分开:攻击者有没有取得可以带走的凭证,以及攻击者有没有利用仍然有效的用户上下文完成操作。

RFC 10017 对恶意 JavaScript 的定位很严格。它一旦进入应用执行环境,就与合法代码拥有同样权限,可以读取页面数据、访问 origin 存储、联系同源窗口,并从合法 origin 向后端发送请求。它不是一个被浏览器自动隔离的次级主体。

标准列出四类路径:一次性盗取现有令牌、持续盗取轮换中的令牌、借新的授权流程取得独立令牌,以及不提取秘密而直接通过用户浏览器代理请求。最后一种正是 BFF 仍然保留的风险。恶意请求与正常请求来自同一执行上下文;若外部组件负责附加访问令牌,它也会为恶意代码诱发的请求附加令牌。

因此,“没有令牌外泄”只能关闭携带和异地重放问题。它不能回答浏览器会话是否调用了错误接口、BFF 是否允许了过宽路径、资源服务器是否把一次技术上有效的调用误当成业务授权。

BFF 改变攻击结果,不改变浏览器

BFF 承担三项核心工作:作为机密 OAuth 客户端与授权服务器交互;在服务器端保存访问令牌与刷新令牌;接受带会话 Cookie 的前端请求,为它选择合适令牌并转发给资源服务器。浏览器看到的是会话接口,不是令牌材料。

这一架构确实阻断重要攻击。浏览器里没有可直接带走的令牌,持续轮换也不会把刷新令牌暴露给脚本;受污染代码即使取得授权码,也缺少 BFF 的客户端凭证来完成交换。PKCE 进一步保护授权码交换过程。

剩余风险同样写得清楚。恶意代码仍在应用 origin 内,可以让用户浏览器向 BFF 发请求。HttpOnly 阻止脚本读取 Cookie,却不会阻止浏览器在合规请求中自动携带它。BFF 随后可能正常找到令牌、补上授权并转发,整个过程中攻击代码不必看见任何秘密。

这就是客户端劫持。攻击者被限制在应用、会话、BFF 映射和资源策略共同允许的动作中,不能自由把令牌拿到别处使用。限制很有价值,却不等于当前代码可信。RFC 因而能够同时强烈建议高风险应用使用 BFF,并明确说恶意代码仍可能通过浏览器代理请求。

Cookie 不可读,不等于会话不工作

RFC 10017 要求 BFF Cookie 使用 Secure 和 HttpOnly,并建议 SameSite=Strict、路径 /、不设置 Domain,以及适当的 host 前缀。这些属性限制网络暴露、脚本读取与跨子域共享。

它们没有证明请求表达用户意图。Cookie 负责认证浏览器与 BFF 的交互,BFF 仍必须部署 CSRF 防护。SameSite=Strict 在孤立站点中很强,但同一 eTLD+1 下的不同子域仍属 same-site,即使它们是 cross-origin。某个兄弟子域被接管时,单纯的 same-site 假设可能失效。

CORS 也必须按实际请求验证。安全清单内的简单请求可能不经过 preflight;浏览器会把请求发出,只是不把响应暴露给调用脚本。若 BFF 依赖 preflight,可要求自定义请求头并在每个入口检查。审计证据应是所有敏感端点都拒绝缺少该头的请求,而不是配置界面里的一项“已启用 CORS”。

会话时钟还应与刷新令牌时钟联动。刷新令牌过期或撤销后,BFF 不应继续展示一个看似有效却无法取得合法访问的会话。反过来,仅撤销令牌而不保存会话关联,也会使调查者无法证明哪些浏览器动作真正停止。

代理映射本身就是授权面

BFF 不只是秘密保险箱。它把入站 Cookie 请求变成带 bearer 令牌的出站请求,是一层应用代理,也是一处决定面。

RFC 10017 要求严格限制出站目标。允许的资源主机应列入清单;动态路径必须校验;每个端点可以限制 HTTP 方法。若映射过宽,攻击者可能把合法会话变成开放转发器,把令牌送往错误主机,或者触及前端从未准备开放的操作。

因此 /bff/orders/{id} 之类路径不是普通管道。它规定浏览器会话可以花费哪些资源、路径和方法。资源服务器仍须验证 audience、scope、主体和动作级政策。BFF 正确选路,并不能证明退款、转账或管理修改符合当前业务授权。

结果证据也不能停在 HTTP 成功。上游可能异步拒绝,BFF 可能重试,多个用户也可能因为共享出口 IP 被资源服务器统一限速。要把会话、请求 ID、路由决定、令牌范围、资源判断和最终业务状态串在一起。

BFF 还集中隐私可见性。所有请求与响应都经过它;如果组件由第三方托管,令牌离开浏览器的风险下降了,第三方能够观察的数据却增加了。凭证安全和数据最小化是两项不同决策。

三种架构留下三套证据

标准按安全性和复杂度比较三种方案。完整 BFF 在服务器端保存两类令牌并代理全部资源请求;token-mediating backend 保存客户端凭证和刷新令牌,却把访问令牌交回浏览器;纯浏览器客户端自行完成 OAuth 并持有令牌。

中间方案不是“半个 BFF”这样简单。它减少刷新令牌失窃和新授权码交换风险,却仍让恶意代码窃取或使用访问令牌。其保管、重放和请求证据与完整 BFF 不同。

纯浏览器方案面临四种恶意代码路径。Authorization Code 加 PKCE 是强制要求;刷新令牌还必须轮换或受 sender constraint,并受最长或闲置期限约束。这些措施限制截获和长期利用,不能隔离已经进入合法 origin 的代码。

DPoP 也有明确边界。不可导出的密钥让偷走的访问令牌更难在浏览器外使用,却无法阻止在原浏览器里代理请求。如果恶意代码还能启动新授权流程,它可能把新令牌绑定到自己控制的密钥。“发送者受限”必须说明是哪一个执行上下文和哪一次流程。

同域前端与 API 也未必需要用 OAuth 表达彼此关系。应用可以在联合认证后维护自己的会话。若没有独立资源方,额外引入 OAuth 可能新增令牌与代理表面,却没有新增清晰的信任边界。

让安全声明与机制一样狭窄

RFC 10017 的力量正在于它没有许诺浏览器安全区。BFF 是降低令牌暴露的强方案,不是对 origin 内所有代码、每次代理请求或最终业务动作的总体背书。

运行记录应分别保存代码和依赖来源、origin、会话签发与到期、Cookie 属性、请求时间、方法、路径、正文类别、CSRF 结果、BFF 映射、令牌 audience 与 scope、资源政策、响应、业务效果和回退负责人。每项证据都有自己的时钟与责任方。

这也是最小协调的意义:共同 BCP 规定安全下限,应用边界、端点清单、异常阈值和可逆性继续由本地决定。架构标签不能替代运行结果。承担欺诈、隐私与中断损失的一方,必须保留准入、观察、停止和逆转动作的最终权限。

来源