忘机山人
在第一章里,我们刻意做了一件事:
完整走完了一次“正常的懒猫 SSO 登录流程”,但没有解释任何安全细节。
如果你回看那个流程,会发现一个非常危险的现象:
整个过程中,ENV 查看器几乎没有“主动验证”任何东西。
它只是:
/sys/oauth/auth/callbackcode然后,很多懒猫 App 就直接宣布:
“登录成功。”
这件事之所以看起来合理,是因为我们在脑海中默认了一整套“看不见的前提”。
而这一章的目的,就是把这些前提全部显性化。
当 ENV 查看器收到一个 id_token 时,通常会发生如下对话(虽然没有写在任何代码里):
懒猫 SSO 说:
“这个 token 代表用户 alice。”
ENV 查看器心里想:
“好,那她就是 alice,还是盒子主人,那我给她管理员视图。”
这个逻辑的问题不在于“不合理”,而在于:
它跳过了所有“为什么我应该相信你”的问题。
在安全系统里,任何跳过“为什么”的设计,都会在后面以事故的形式补回来。
而在家庭服务器这种主人和被邀请家人共用一个盒子的场景下,
“我该不该把 Alice 当成管理员”这个判断,一旦出错,后果不可逆。
我们先不谈攻击者。
只从逻辑完整性出发,把 ENV 查看器在“信任登录结果”时,隐含接受的假设列出来:
xu.deploy.env 这个 Client 用的,而不是发给盒子上另一个应用的你会发现一个事实:
流程中,并没有任何一步“天然保证”这些假设成立。
换句话说:
流程跑通 ≠ 假设成立
很多懒猫 App 开发者第一次接触这个问题时,会产生一个非常自然的反应:
“这些假设在家庭内网里几乎总是成立的吧?我家又没有 APT。”
这正是问题的核心。
安全系统设计的第一原则是:
不要基于“通常如此”来建立信任。
尤其在懒猫这种场景下,“通常”其实比你想的更脆弱:
heiyu.space 的公网访问)OIDC 的设计,建立在一个非常保守的前提之上:
假设浏览器、网络、中间环境,全部是不可信的。
懒猫 SSO 继承了这个前提,你作为 App 开发者也必须继承。
到这里,你可能会反问一句:
“那 HTTPS 呢?我的
alice.heiyu.space是懒猫官方给我签的证书,
不是已经很安全了吗?”
这是一个非常关键的问题。
HTTPS 确实解决了很多问题,但它解决的是:
但 HTTPS 不解决下面这些问题:
xu.deploy.env 的,还是给盒子上别的 App 的也就是说:
HTTPS 保护的是“通道”,
懒猫 SSO 必须解决的是“内容”。
另一个常见的直觉是:
“我信任懒猫这个盒子,那懒猫返回的结果我就直接信。”
这句话在逻辑上是不完整的。
因为它混淆了两个不同层面的“信任”:
即使你 100% 信任懒猫 SSO 本身,也不能跳过第二层。
原因很简单:
同一个懒猫 SSO 同时为盒子上所有 App 服务。
如果 ENV 查看器不明确验证:
xu.deploy.env)的?”那么一个合法但不相关的结果,就可能被错误使用。
比如:另一个 App(哪怕是善意的)拿到了懒猫 SSO 发给它自己的 token,
阴差阳错传给了 ENV 查看器,
ENV 查看器如果不检查 aud,就会用一个不属于自己的 token 完成登录。
这不是科幻。在懒猫这种“应用彼此能互联”的架构下,aud 检查是基础操作。
到目前为止,我们其实已经得到一个非常重要的结论:
“登录成功”不是一个瞬间事件,
而是一个逐步建立的信任过程。
这个过程不是靠“感觉安全”,而是靠一连串明确的验证步骤。
我们可以把它抽象成一句话:
懒猫 SSO 的核心不是“身份声明”,
而是“身份声明的验证链”。
懒猫只是把这条链的起点和工具替你准备好了(注入环境变量、生成 client_secret、暴露 discovery),
但链上的每一环都还是你自己负责执行的。
如果你回到第一章的流程,会发现一个关键事实:
在 token 出现之前,
ENV 查看器已经接收过一个“关键输入”。
那就是:
https://env.alice.heiyu.space/callback?code=abc123&state=xyz
这个 code,决定了 ENV 查看器能否拿到后续的一切。
于是,一个新的问题浮现出来:
如果 code 本身被滥用,
后面再严格的 token 校验,还有意义吗?
这不是一个修辞问题。
这是 PKCE 出现的直接原因,也是懒猫 SSO 为什么在 discovery 里明确声明
code_challenge_methods_supported: ["S256", "plain"] 的原因。
我们可以用几句话,把这一章的核心结论说清楚:
换句话说:
如果你只验证 token,
那你已经晚了一步。
在下一章中,我们将回到那个被忽略的问题:
Authorization Code 暴露在浏览器里,
为什么在懒猫场景下还敢用?
我们会看到:
CLIENT_SECRET,但在某些场景下它实际上是 public 的这是 懒猫 SSO 验证链的第一道真正闸门。
懒猫 SSO 的安全性,不来自“我信任懒猫”,
而来自“我验证过这次结果”。

评论
0暂无评论