Chrome 开始正式部署 DBSC(Device Bound Session Credentials,设备绑定会话凭证)。Ars Technica 8 月 12 日的报道把它称作"目前对抗账号接管最有效的保护之一",但真正有意思的东西不在新闻里,在 WICG 的规范文档里。
问题的本质:Cookie 是 bearer token
桌面操作系统的进程隔离一直很薄。恶意软件跑在用户态就能读到浏览器能读的一切,而浏览器必须能读 Cookie,所以恶意软件也能读。Chrome 的 Cookies SQLite 库和 Local State 里的 App-Bound 加密密钥,就是 infostealer 的标准作业流程:打包、上传、在灰产市场按域名明码标价。二次利用者不需要碰你的设备,拿一串 Cookie 就能以你的身份发请求。
DBSC 的切入点不是把 Cookie 藏得更深,而是让偷来的 Cookie 不够用。会话认证从 bearer token 变成"持有私钥并能定期证明",私钥由 TPM 这类系统级保护托管,恶意的浏览器进程读不出来。
规范里对威胁模型写得很直白。主威胁是能读写 user agent 的本地恶意软件,可能已经拿到 root 或内核权限。目标不是阻止攻击者在驻留期间访问会话,而是要保证"临时读写权限不等于长期接管"——恶意软件被清掉之后,它偷走的会话凭证不再可用。这个"长期"的边界由服务端配置的刷新周期决定。
非目标同样明确:攻击者如果持续驻留,可以把安全芯片当签名 oracle 用,照样持续拿到新 Cookie。次级场景还有网络中间人、服务端把完整请求头写进日志被无权限内部人员读到——短命 Cookie 让这类泄漏的收益急剧下降。
注册:一个响应头触发建钥
服务端在登录成功的响应里带一个结构化头:
HTTP/1.1 200 OK
Secure-Session-Registration: (RS256 ES256);challenge="challenge_value";path="StartSession"
括号里是可接受签名算法的列表(只有 ES256 和 RS256),path 必填,指协商注册的端点,challenge 是给注册 JWT 用的挑战值。一个响应可以带多条 registration,也可以合并成一条用逗号分隔。可选的 authorization 属性会把一个 bearer token 透传到注册端点的 Authorization 头,方便服务端把注册动作绑定到前面的登录流程,OAuth 2.0 那套基础设施不用重写。
浏览器选一个算法、生成设备绑定的密钥对(Chrome on Windows 用 TPM 背书,协议本身不限定实现),然后发:
POST /securesession/startsession HTTP/1.1
Host: auth.example.com
Accept: application/json
Secure-Session-Response: <JWT proof>
JWT 的头部是 {"alg":"ES256","typ":"dbsc+jwt","jwk":<公钥 JWK>},载荷只有 jti(就是那个 challenge)和可选的 authorization。这里有个刻意的设计:TPM 的证书链永不上传。否则服务端就能拿它做高精度设备指纹,和隐私目标冲突。服务端能确认的只有一件事——对面还持有对应的私钥。
注册成功后服务端回一段 JSON,这才是整个协议的核心配置:
{
"session_identifier": "session_id",
"refresh_url": "/RefreshEndpoint",
"scope": {
"origin": "https://example.com",
"include_site": true,
"scope_specification": [
{ "type": "include", "domain": "trusted.example.com", "path": "/only_trusted_path" },
{ "type": "exclude", "domain": "*.example.com", "path": "/static" }
]
},
"credentials": [{
"type": "cookie",
"name": "auth_cookie",
"attributes": "Domain=example.com; Path=/; Secure; HttpOnly; SameSite=None"
}]
}
credentials 声明这次会话要保证存在哪个 Cookie,属性按 RFC 6265bis 解析。Max-Age 和 Expires 不参与"请求是否满足条件"的判定,所以 Cookie 可以短命。同一响应里用普通的 Set-Cookie 把这个短命 Cookie 发下去,示例里是 Max-Age=600。
刷新:把"Cookie 不存在"变成一次带证明的补票
只要 Cookie 还没过期,浏览器行为完全不变。Cookie 一过期,落到 scope 内的请求就不会直接发出去,浏览器先做一轮刷新:
POST /securesession/refresh HTTP/1.1
Host: auth.example.com
Sec-Secure-Session-Id: session_id
服务端可以在这时候要求持有证明,回 403 加挑战头:
HTTP/1.1 403
Secure-Session-Challenge: "challenge_value";id="session_id"
挑战也可以提前挂在任意响应上做优化,甚至可以一次性给多个会话发。浏览器用同一个密钥签一个 JWT 回过去,然后服务端 Set-Cookie 下发新的短命 Cookie,浏览器把之前挂起的请求连同新 Cookie 一起放行。
这套设计对工程团队的价值在于:非认证端点不需要容忍未认证请求,也不需要写重试或跳转逻辑,它们看到的永远是普通 Cookie,唯一区别是这些 Cookie 命短。会话绑定的逻辑集中到登录环节和刷新端点两处,横跨多个团队、多个 RPC 框架的老系统不用大改。代价是延迟——请求被按住了。浏览器可以用预测性刷新来缓解,在 Cookie 快过期时提前换好,规范里说这是纯延迟优化,不是必需行为。
会话结束有三条路:刷新时回 {"continue": false}、任意时候发 Clear-Site-Data: "cookies" 或 "storage"、或者用户清站点数据。规范特别强调最后一条,用户必须始终能删掉绑定的密钥。
TPM 这笔账算得过来吗
Chrome 团队做过统计:约 60% 的 Windows 用户(还在增长)能获得这层保护,签名延迟 P50 是 200ms,P95 是 600ms,错误率约 0.001%,算法用的是 ECDSA_P256。
200ms 听起来很贵,但刷新频率是分钟级而不是请求级。真正被这 200ms 挡住的是第一条发现 Cookie 过期的请求,之后的请求都在 Cookie 有效期内正常跑。P95 600ms 的尾部延迟才是要盯的地方,特别是用户刚做完敏感操作、Cookie 刚好过期的时刻。
TPM 的不可靠名声是真实存在的,所以协议不强制 TPM,实现方可以用 VBS key 之类的方案。协议层只要求密钥不可导出。
它挡不住什么
DBSC 不管同源 XSS。脚本能发请求,就能用会话,密钥在浏览器手里,跟攻击者借浏览器的手没有区别。它也挡不住注册时就已经驻留的恶意软件——密钥生成那一刻恶意代码就在旁边,等于全程可用。
这就是 DBSC(E) 要解决的问题。它引入设备密钥链:设备级密钥先打好底,会话密钥由设备密钥派生或背书,注册时被感染的设备无法把会话密钥搬到别处。对企业的意义比对个人大。
隐私上有几条硬约束值得记住:清站点数据必须清密钥和会话(不许当伪 Cookie 用);不能泄漏稳定的 TPM 标识;跨站刷新要受第三方 Cookie 策略和 Storage Access API 约束;主动刷新只在有标签页加载着该站点时发生。每一条都是为了防止这套机制变成新的追踪面。
服务端落地要动的三处
我在自己的项目里评估过一遍,改造成本比预期低,但有三处必须对齐。
第一,登录成功时下发 Secure-Session-Registration,把 challenge 一次性绑定到这次登录的 nonce 上,注册端点验签 JWT 时检查 jti 是否用过的挑战值。
第二,实现 refresh 端点。它要做的事只有两件:验 Secure-Session-Response 的签名,然后 Set-Cookie 一个新的短命 Cookie。把原来的长命 Cookie 的 Max-Age 从几天压到 600 秒,业务代码一行不用改。
第三,Cookie 属性必须和 credentials.attributes 逐字段一致。Domain、Path、Secure、HttpOnly、SameSite 对不上,浏览器就不认为 Cookie 满足条件,于是每次都触发刷新,直接把自己的登录路径打成 DDoS。
灰度建议先切一个第一方路径,重点监控两个指标:被挂起请求的数量和延迟分布,以及验签失败率。另外一定要留退路——用户设备上没有可用 TPM、或者驱动抽风签名失败时,服务端得能退回普通长命会话,否则这层保护会先把用户锁在门外。对不支持 DBSC 的浏览器保持老路径不变,两种情况在服务端最好走同一套会话表,只是 Cookie 寿命不同。
⚠️ 网络安全免责声明
本文内容仅供技术研究与安全学习之用。文中描述的协议设计、攻击面分析和配置示例均基于公开披露的技术规范,旨在帮助开发者理解认证机制、提升安全意识和防御能力。
请勿将本文所述技术用于任何未经授权的安全测试、渗透攻击或非法用途。任何因滥用本文信息而造成的法律后果,由使用者自行承担,与本文作者无关。
如发现系统安全漏洞,请通过合法渠道向相关厂商或平台报告,共同维护网络安全生态。
浙公网安备 33010602011771号