资讯动态

CVE-2026-29000 到底影响哪些包?我查错了一次(附离线排查工具)

发布时间:2026/8/7 9:48:52 来源:尧图企业网站定制
更正:这篇文章原来的核心结论是错的(2026-08-06)本文最初的结论是「CVE-2026-29000 的官方 advisory 只列了 1 个包,实际有 5 个,通过pac4j-oidc间接依赖的人 Dependabot 不会告警」。这个说法不成立。官方 advisory 只列org.pac4j:pac4j-jwt,是对的。我确实逐个解析了 Maven Central 上的 pom,也确实看到pac4j-oidc的 pom 里写着pac4j-jwt这个坐标 ——但我没看scope。如果你因为这篇文章升级过 pac4j:那次升级不是必需的(升级本身无害)。真正需要处置的,只有「你的应用里确实存在受影响版本的pac4j-jwt」这一种情况。下面是重写后的正文。错在哪、怎么发现的,写在第三节,那部分可能比原文更值得看。这个漏洞本身(这部分原文没错)org.pac4j:pac4j-jwt的JwtAuthenticator在处理加密 JWT(JWE)时,某些路径下不强制校验签名。攻击者只要拿到服务器的RSA 公钥—— 公钥本来就是公开的 ——就能构造一个 JWE 包裹的 PlainJWT,把 subject 和 role 字段写成任意值,以任意用户身份登录,包括管理员。不需要任何凭据。CVSS10.0,满分。GitHub advisory 编号GHSA-pm7g-w2cf-q238,公开于 2026-03-05。受影响范围就是官方 advisory 写的那三段,没有更多:org.pac4j:pac4j-jwt 4.5.9 - 修复版 4.5.9 5.0.0-RC1 且 5.7.9 - 修复版 5.7.9 6.0.4.1 且 6.3.3 - 修复版 6.3.3我原来的推理是怎么走偏的pac4j 是个多模块项目。做 OIDC 单点登录的人引的是pac4j-oidc,很少有人直接引pac4j-jwt。所以我去查:哪些兄弟模块会把pac4j-jwt带进来?方法是从repo1.maven.org拉org.pac4j下全部 76 个 artifact 的maven-metadata.xml,逐个版本下载 pom,看谁引用了pac4j-jwt。我找到了 4 个,于是得出「官方漏了 4 个包」。这一步的数据是真的,结论是错的。因为 pom 里的每一条依赖还有一个scope,而我没看。看了 scope 之后pac4j-oidc - pac4j-jwt scopetest javalin-pac4j - pac4j-jwt scopetest lagom-pac4j-parent - pac4j-jwt scopeprovided ratpack-pac4j 1.4.6 - 那段依赖整块被 XML 注释包着,根本不存在pac4j-oidc我是逐版本核的:3.0.0、4.0.0、4.5.0、5.0.0、5.7.0、6.0.0、6.3.0,全是test,无一例外。Maven 的规则是:test和provided依赖不会传递给下游使用者。它们只在这个模块自己编译和跑测试时存在。所以你的项目引pac4j-oidc,Maven 不会把pac4j-jwt放进你的 runtime classpath。光看 pom 我还不放心,又下载了真实构件复核了一次:pac4j-oidc-6.0.0.jar 共 78 个条目,全部在 org/pac4j/oidc/ 下 没有任何 shade 进来的 pac4j-jwt 类不传递依赖,也不打包携带 ——两条路都不通,使用者拿不到 pac4j-jwt。那个ratpack-pac4j 1.4.6尤其值得一提:grep 能搜到pac4j-jwt这个字符串,因为它确实写在文件里 —— 但整段被!--包着。XML 解析器看得见的东西,和 grep 看得见的不是一回事。有一件事我想单独说:自校验为什么没拦住原文里我专门写过一节叫「怎么确认我的数字没算错」,内容是:把判定规则跑在 pac4j-jwt 全部 147 个版本上,命中114个,而官方三段区间声明的版本数是 13 33 68 114,精确吻合,这条断言还写死在单元测试里,对不上就构建失败。这个自校验本身没有任何问题,它今天依然是绿的。问题是它验证的是「版本区间算法对不对」,而我的错误发生在「哪些构件该进这张表」——它压根管不到那一层。而当时我把它当成了整张表可信的证明。校验通过的范围,不等于结论成立的范围。更让我记住这一条的是:原文倒数第二节里,我还写着「判定规则错了不叫误报,是让人做错事」,说的是上一个工具栽过的跟头。结果同一篇文章介绍的工具,犯了同一类错。工具还在,已经修好pac4j-check:单个 jar,零运行时依赖,Java 8 起可用,完全离线,不联网、不上传数据。java -jar pac4j-check.jar ./myapp.jar # 扫一个 jar/war java -jar pac4j-check.jar /opt/apps # 扫一个目录(递归) java -jar pac4j-check.jar /opt/apps --json # JSON 输出v0.2.0 删掉了那套「引入者」推断 —— 它的逻辑是「没看见 pac4j-jwt,但看见了 pac4j-oidc,于是断定 jwt 也在」,在没有证据的情况下报警,而那个推断是错的。原来断言这些误报的单元测试,现在反过来断言「不再误报」,免得哪天又改回去。它现在只做一件事,但这件事mvn dependency:tree做不到:直接扫构件本身,判断受影响版本的pac4j-jwt到底在不在。递归展开 Spring Boot fat-JAR(在内存里,不解压落地)——生产机上往往只有一个打好的 jar,没有源码和 pom识别被 shade 进宿主 jar 的情况—— 依赖树上根本不出现这个节点退出码0/1/2,可以直接挂 CI。你现在可以做的确认你的应用里有没有受影响版本的org.pac4j:pac4j-jwt—— 直接依赖或传递依赖都算如果在上面那三段区间里,升到对应的修复版本只引pac4j-oidc而没有pac4j-jwt的,不受这个 CVE 影响—— 这正是我原来说反的地方工具和完整数据都在:https://github.com/xiaoqiMikko/pac4j-check原文我没有删除、也没有假装它不存在,错误的推理过程和更正都留在上面。如果你发现我哪里还有错,欢迎开 Issue 指出来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价