☰
treg会话Cookie安全设计:treg_session如何防止泄露到上游
2026/9/28 21:20:22 网站建设 项目流程

treg会话Cookie安全设计:treg_session如何防止泄露到上游

【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址: https://gitcode.com/GitHub_Trending/treg/treg

treg 是一个面向 Agent 工具的 API 网关("OpenRouter for agent tools"),它的核心工作是把用户的请求中继(relay)到上游数据服务商。这种"替浏览器转发请求"的模式天然带有一个安全隐患:用户在仪表盘上登录 treg 时浏览器持有treg_session会话 Cookie,如果它被原样转发给第三方上游,等于把"钥匙"交给了陌生人。这篇文章讲清楚 treg 是如何用签名会话 + 双向 Cookie 清洗 + 受众隔离三层设计,把treg_session牢牢锁在网关内部的。

一、为什么中继网关特别怕会话 Cookie 泄露

treg 的中继层承诺"忠实验证式转发":方法、路径、查询参数、请求头、Cookie、请求体字节流,几乎原样透传。这对 API 调试和凭证注入是必需的,但也意味着——

浏览器里发出的每一个 Cookie,如果不加区分,都会被复制进发往上游的请求头中。

而 treg 的仪表盘前端在 "Try it" 试调用场景下使用了credentials: 'include'(让浏览器自动带上同源 Cookie),会话 Cookie 就必然出现在请求里。上游服务商是第三方,一旦拿到treg_session,理论上可以反向调用 treg 的会话接口,冒充该用户操作其团队、密钥和账单。

所以整个安全设计围绕一个目标:让treg_session永远只属于 treg 这一个域,绝不跨出网关。

二、签发环节:一个"上不了台面"的签名 Cookie

treg_session的定义和签发逻辑位于 session.py,它不是服务端数据库里存的一串随机值,而是一枚无状态 HMAC-SHA256 签名令牌,内嵌三类声明(claims):

声明含义安全作用
uid用户 ID标识会话归属
exp过期时间戳固定 7 天有效期(TTL_SECONDS)
aud受众 =session⭐ 与 API 密钥(identity)硬性隔离

设置 Cookie 时(见 auth.py)同时叠加了浏览器侧的标准防御:

  • HttpOnly:JavaScript 读不到,XSS 拿不走;
  • SameSite=Lax:跨站请求默认不带,抗 CSRF;
  • Secure:HTTPS 环境下仅加密传输;
  • max_age= 7 天:自动过期。

还有一个细节值得注意:如果没有配置签名密钥,treg不会退化成代码里写死的默认密钥(那会让任何读源码的人伪造任意用户的 Cookie,包括超级管理员),而是用每进程随机的临时密钥——代价是重启后登录失效,但这是"宁可响亮地失败,也不能静默地裸奔"的选择(见 session.py 的注释)。

三、核心防线:中继层的双向 Cookie 清洗

真正的主角在中继函数relay()里,实现在 relay.py。它做了一次双向清洗:

1️⃣ 出方向:treg_session到不了上游

def _scrub_treg_cookies(headers): # 从 Cookie 头中摘掉 treg 自己的 Cookie,其余调用方 Cookie 保留 # 摘空了就整个删掉 Cookie 头

转发前,relay()会解析Cookie头,精确剔除treg_session和treg_oauth_state(见 _TREG_COOKIES),而用户自己的其他 Cookie 原样保留——不会误伤。

浏览器发出: Cookie: treg_session=abc123; ordinary=keep-me 转发上游: Cookie: ordinary=keep-me ✅ treg_session 被扣下

2️⃣ 入方向:上游也不能反向"种"你的会话 Cookie

更隐蔽的攻击是会话固定:上游返回一个Set-Cookie: treg_session=evil,由于响应经过 treg 同域代理,浏览器会把这个伪造值种到 treg 域名下,覆盖真实会话。

relay()在回传响应头时,凡是针对 treg 自家 Cookie 名的Set-Cookie一律丢弃(见 _is_treg_setcookie),同时给每个中继响应追加X-Content-Type-Options: nosniff和Content-Security-Policy: sandbox,防止上游 HTML 在 treg 源下执行脚本(反射型 XSS 的最后一道闸)。

四、受众隔离:会话令牌变不成 API 密钥

单靠清洗只挡住了"传输路径"。treg 还在令牌本身做了身份互斥:

  • 浏览器会话签发的令牌aud = "session";
  • API 密钥 / Bearer 令牌aud = "identity";
  • read_session_claims() 拒绝一切非session受众的令牌,read_identity_claims() 则无条件拒绝session受众令牌。

即使某条路径的清洗出现漏洞,treg_session被复制走了也没用——它无法通过X-Treg-Token通道重放,反之 API 密钥也不能冒充浏览器登录。两套身份,互不串门。

五、回归测试:F3 用例双向验证

这套设计被固化在调用矩阵测试 F3 中(test_matrix.py,说明见 CASES.md):

  1. 请求携带treg_session=caller-secret; ordinary=keep-me→ 断言上游收不到treg_session,自定义头与ordinary保留;
  2. 上游模拟返回Set-Cookie: treg_session=evil→ 断言该头不出现在回传响应中。

双向各一条断言,防止任何一侧的清洗回归。

六、参考文件清单

模块路径说明
会话令牌签发/校验src/treg/domain/identity/session.pyHMAC 令牌、受众分离
中继 Cookie 清洗src/treg/infra/upstream/relay.py双向 scrub 逻辑
Cookie 属性设置src/treg/routers/auth.pyHttpOnly / Lax / Secure
代理模型文档docs/context/architecture/proxy-model.md转发忠实性契约
认证与密钥架构docs/context/architecture/auth-secrets.md会话生命周期
双向清洗测试tests/callmatrix/test_matrix.pyF3 用例

七、一句话总结

🔒 treg 的安全思路不是"把 Cookie 藏起来",而是假设它一定会出现在请求里,然后在三个层面同时设防:

  1. 令牌自身:签名 + 7 天过期 +aud受众隔离,泄露也变不成别的身份;
  2. 出方向:_scrub_treg_cookies在中继前精确摘除,只扣自家的、不误伤用户的;
  3. 入方向:拒绝上游反向种植同名 Cookie,杜绝会话固定。

对任何做代理/网关类产品的人来说,这套"清洗 + 隔离 + 固定化测试"的组合拳,都是一份可以直接抄作业的防泄露清单。

【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址: https://gitcode.com/GitHub_Trending/treg/treg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询