OpenAM 会话令牌窃取与 SAML 绕过(CVE-2026-123551)
OpenAM 16.1.4 之前的版本泄露实时会话令牌并接受未签名的 SAML 断言,未认证攻击者可劫持会话;已在 16.1.4 修复。
TL;DR
- OpenAM 16.1.4 之前的版本把实时会话令牌以明文发送到策略代理主题,并在 ECP 与 HTTP-Artifact 绑定上接受未签名的 SAML 断言。未认证攻击者可用任一缺陷劫持用户和管理员会话。
- 同一版本还修复了一个自助注册缺陷,该缺陷允许匿名用户加入管理组。OpenIdentityPlatform 于 2026 年 10 月 22 日发布了公告和 OpenAM 16.1.4。
- CVE 记录将会话令牌泄露评为 CVSS v4.0 10.0,另外两个缺陷评为 9.3。厂商公告将会话令牌缺陷评为 CVSS v3.1 10.0,另外两个评为 9.8。
- 没有公开的概念验证,也没有在真实环境中被利用的报告。截至 2026 年 11 月 8 日,这些缺陷不在 CISA 的 KEV 目录中。请升级到 OpenAM 16.1.4。
我受影响吗?
必须同时满足以下所有条件:
- 您运行的是 16.1.4 之前的 OpenIdentityPlatform OpenAM。
- 对于会话令牌缺陷,您运行 14.0.0 至 16.1.3,且通知 WebSocket 可访问。代理通知默认启用,正是它把会话标识符放到代理主题上。
- 对于 SAML 缺陷,OpenAM 作为托管 SAML v2.0 服务提供者运行。其元数据公布 ECP(PAOS)断言消费服务,生成的元数据默认如此。服务提供者的
WantAssertionsSigned为 false,生成的元数据也默认为 false,并且配置了加密密钥,以便身份提供者可以向其加密断言。 - 对于自助注册缺陷,该领域启用了自助注册。它默认关闭。
| 分支 | 受影响版本 | 修复版本 |
|---|---|---|
| OpenAM 14.0.0 至 16.1.3 | 全部三个缺陷 | 16.1.4(2026 年 10 月 22 日) |
| OpenAM 14.0.0 之前 | SAML 断言绕过和自助注册提权;通知 WebSocket 不存在 | 16.1.4(2026 年 10 月 22 日) |
版本端点无需会话即可响应。直接询问服务器:
curl -s https://openam.example.com:8443/openam/json/serverinfo/version
响应包含 version、revision 和 date。在容器镜像中,同一请求发往本地端口:
docker exec openam curl -s http://localhost:8080/openam/json/serverinfo/version
如何修复?
请升级到 OpenAM 16.1.4 或更高版本。厂商于 2026 年 10 月 22 日发布,与公告同日。
- 对于容器镜像,在 Compose 文件中将服务设置为
openidentityplatform/openam:16.1.4。拉取所配置的镜像并重新创建容器:
docker compose pull openam
docker compose up -d openam
-
对于 WAR 部署,从 Maven Central 下载
openam-server-only16.1.4,并将新的openam.war覆盖部署到现有 Web 应用。部署后重启容器。 -
对于依赖 OpenAM 构件的 Maven 构建,将
org.openidentityplatform.openam:openam-server-only和其他 OpenAM 模块固定为16.1.4。
如果无法立即升级,以下缓解措施可降低暴露面,但不会修复代码:
- 在每个托管 SAML v2.0 服务提供者上将
WantAssertionsSigned设为 true,并启用响应签名。这覆盖断言缺陷。它不覆盖通知 WebSocket 或自助注册。 - 在反向代理或网络层将
/openam/notificationsWebSocket 和旧版 Liberty ID-FF 端点限制为策略代理主机。这缩小令牌泄露路径。它无法阻止通过其他路径到达这些端点的攻击者。 - 在每个领域禁用自助注册。这只关闭匿名注册路径。
- 将升级前面向互联网的每个 OpenAM 实例视为已暴露,并在升级后检查其会话和管理员账户。
根本原因是什么?
OpenAM 只在 HTTP-POST 绑定上执行 SAML 签名继承。其他所有绑定都依赖一个元数据标志,而其生成的服务提供者元数据将该标志设为 false。 检查位于联合库的 SAML2Utils.verifyResponse 中,在 OpenAM 16.1.3 中如下:
if (wantAssertionsSigned && !(responseIsSigned || allAssertionsSigned)) {
throw new SAML2Exception(bundle.getString("assertionNotSigned"));
}
if (profileBinding.equals(SAML2Constants.HTTP_POST)) {
boolean wantPostResponseSigned = SAML2Utils
.wantPOSTResponseSigned(orgName, hostEntityId, SAML2Constants.SP_ROLE);
if (wantPostResponseSigned && !responseIsSigned) {
throw new SAML2Exception(bundle.getString("responseNotSigned"));
}
if (!responseIsSigned && !allAssertionsSigned) {
throw new SAML2Exception(bundle.getString("assertionNotSigned"));
}
}
第一个代码块仅在服务提供者的 WantAssertionsSigned 元数据为 true 时拒绝未签名的响应。第二个代码块无论该标志如何都会拒绝未签名响应或断言,但它只对 HTTP_POST 执行。在 ECP(PAOS)和 HTTP-Artifact 绑定上,如果元数据标志关闭,两个代码块都不要求签名。
通知 WebSocket 依赖容器执行其过滤器,而过滤器只映射到请求分派。 WebSocket 处理程序让客户端订阅其指定的任意主题:
String topic = json.get("topic").asString();
subscription.bindTo(Topic.of(topic));
安全过滤器读取代理 Cookie,并检查令牌是否属于 J2EE 或 Web 策略代理。在 OpenAM 16.1.3 中,它在 web.xml 中的映射未指定任何分派器,因此容器只在 REQUEST 分派上运行它。
发往 /notifications 的内部转发以 FORWARD 分派到达。过滤器被跳过,WebSocket 升级在没有代理检查的情况下继续。OpenAM 的旧版 Liberty ID-FF 端点会执行此类转发。公告将未经验证的内部转发列为无需凭据到达该套接字的方式。
匿名自助注册操作使用系统管理员令牌创建账户。它从未应用属性允许列表。 在 16.1.3 的 IdentityResourceV2.anonymousCreate 中,请求正文直接进入身份服务:
SSOToken admin = RestUtils.getToken();
return createInstance(admin, jVal, realm, context, null)
允许列表位于 IdentityRestUtils,只适用于携带 SelfServiceContext 的请求。旧版操作不携带它,因此调用者可以设置任意属性。memberof 值不会保留为属性:身份层会将其转换为组成员关系。因此,自助注册用户可以加入管理组。
如何被利用?
SAML 路径无需凭据,也无需用户交互:
- 攻击者在受影响的 OpenAM 实例上找到托管 SAML v2.0 服务提供者。它公布 ECP(PAOS),
WantAssertionsSigned关闭,并配置了加密密钥。 - 攻击者构造一个 SAML 响应,其中的断言指定目标账户(包括管理员),并在没有签名的情况下将其发送到 ECP 或 HTTP-Artifact 端点。
- OpenAM 根据信任圈检查颁发者,但不检查该绑定上的签名。它将断言映射到本地账户并颁发会话。
- 攻击者使用该会话访问 OpenAM 以及依赖它进行单点登录的每个应用。
通知路径需要一条通往 WebSocket 的路由:
- 攻击者向一个旧版 Liberty ID-FF 端点发送请求,该端点内部转发到
/notifications。转发跳过检查策略代理令牌的过滤器。 - 攻击者订阅内部主题。修复前,处理程序接受任意主题名称。
- OpenAM 在会话创建、注销、超时和属性变更时发布完整的
iPlanetDirectoryPro值,因为代理通知默认启用。 - 攻击者将捕获的值作为持有者凭据,对 OpenAM 的 REST 端点以及信任同一会话的应用重放。
自助注册路径需要启用自助注册:
- 攻击者完成其控制地址的电子邮件验证。
- 攻击者发送
anonymousCreate操作,并附带指定管理组的memberof值。 - OpenAM 使用其系统管理员令牌创建账户并写入组成员关系。新账户可以管理该领域。
三个缺陷都没有公开的概念验证。公告表示,技术细节和概念验证代码被保留,以便运维人员有时间升级。
攻击如何展开?
一个未签名的 SAML 断言到达只会在另一绑定上检查签名的服务提供者,映射到本地账户,并成为 OpenAM 背后每个应用的会话。
SAML 断言"] --> B["发送到 ECP 或
HTTP-Artifact 端点"] B --> C["SP 只在 HTTP-POST 上
检查签名"] C --> D["该绑定上
没有签名检查"] D --> E["断言映射到本地用户,
包括管理员"] E --> F["OpenAM 颁发会话"] F --> G["攻击者访问信任 OpenAM 的
每个应用"]
攻击者能做什么?
SAML 缺陷让未认证攻击者以服务提供者能够映射的任意账户获得会话,包括管理员账户。可到达的账户取决于映射方式。
自动联合或将 NameID 用作用户标识符可以到达任意账户。如果联合标识符是电子邮件地址或用户名,攻击者可以到达其知道或能猜出标识符的任意账户。攻击者继承信任被劫持会话的每个应用。
通知缺陷让未认证攻击者在 WebSocket 连接打开期间读取每个会话被创建、更改或结束的用户的实时会话令牌。这包括管理员。令牌是对 OpenAM REST API 以及同一会话背后每个应用的持有者凭据。攻击者还可以订阅内部主题。
自助注册缺陷让匿名攻击者创建一个属于任意现有组(包括管理组)的账户。存在此类组时,结果是该领域的完全管理控制。攻击者需要启用自助注册,而这不是默认配置。
三个 CVE 记录都将每个缺陷评为严重:令牌泄露为 CVSS v4.0 10.0,另外两个为 9.3。
三个缺陷都不需要本地位置。SAML 和通知缺陷可通过网络到达。自助注册缺陷在功能开启时可通过网络到达。
为什么修复有效?
SAML 修复将签名决策放在所有其他检查之前,并应用于每个绑定。提交添加了 isMissingRequiredSignature。当响应及其所有断言都未签名时,它会拒绝该响应,除非绑定是后端 HTTP-Artifact 绑定且其配置允许。摘录仅保留该检查和抛出:
+boolean allAssertionsSigned = true;
+List<String> unsignedAssertionIDs = new ArrayList<>();
+for (Assertion assertion : assertions) {
+ if (!assertion.isSigned()) {
+ allAssertionsSigned = false;
+ unsignedAssertionIDs.add(assertion.getID());
+ }
+}
+if (isMissingRequiredSignature(responseIsSigned, allAssertionsSigned,
+ () -> isAssertionSignatureRequired(wantAssertionsSigned, profileBinding, spConfig, orgName,
+ hostEntityId))) {
+ throw new SAML2Exception(bundle.getString("assertionNotSigned"));
+}
同一提交将 HTTP-Artifact 响应绑定到解析该工件的身份提供者,这样一个受信任伙伴无法用以另一伙伴名义颁发的响应来应答。该修复对公告所述的服务提供者响应路径是完整的。
WebSocket 修复添加主题允许列表,并让过滤器在所有分派类型上运行:
+private static final String ALLOWED_TOPIC_PREFIX = "/agent/";
+if (!topic.startsWith(ALLOWED_TOPIC_PREFIX)) {
+ sendError(session, id, "topic not permitted");
+ return;
+}
<filter-mapping>
<filter-name>NotificationsWebSocketFilter</filter-name>
<url-pattern>/notifications</url-pattern>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>FORWARD</dispatcher>
+ <dispatcher>INCLUDE</dispatcher>
+ <dispatcher>ASYNC</dispatcher>
+ <dispatcher>ERROR</dispatcher>
</filter-mapping>
联合代码还会拒绝转发到带有仅请求过滤器的根路径。该修复覆盖公告所述到达套接字的两种方式。
自助注册修复在任何 SelfServiceContext 之外显式应用允许列表:
+if (!USER_TYPE.equals(objectType)) {
+ throw new BadRequestException("Self-registration is only supported for users");
+}
+removeIgnoringCase(jVal, EMAIL);
+removeIgnoringCase(jVal, FIELD_MAIL);
+jVal.put(FIELD_MAIL, email);
+enforceSelfRegistrationWhiteList(configHandler, realm, jVal, objectType);
允许列表检查还会拒绝不允许的组成员关系,不区分大小写地比较属性名称,并拒绝无法转换的正文。身份仍使用管理员令牌创建,但只带有允许列表允许的属性。
如何检查是否已遭入侵?
没有发布入侵指标,公告也表示没有报告利用。请将这些视为线索而非证据,并注意失败的尝试可能不留痕迹。
首先检查版本,因为其他所有检查都依赖它。然后查找通过联合端点创建、但没有对应身份提供者登录的会话。还要查找通过自助注册创建且属于管理组的账户,以及来自非策略代理主机的 /openam/notifications WebSocket 连接。
反向代理访问日志记录 WebSocket 路径:
grep -iE "GET /openam/notifications|anonymousCreate" /var/log/nginx/access.log
OpenAM 审计日志以 JSON 记录身份和会话事件。在审计目录中搜索您调查期间的身份创建和会话事件:
grep -hE '"eventName": ?"AM-(IDENTITY|SESSION)"' /path/to/openam/audit/*.json | tail -n 200
如果未启用审计日志,请在升级前启用并保留现有日志。注销前捕获的会话令牌在过期前仍然有效。如果您有理由怀疑暴露,请在升级后撤销活动会话。
时间线
- 2026 年 10 月 21 日:OpenAM 提交 SAML、通知 WebSocket 和自助注册缺陷的修复。
- 2026 年 10 月 22 日:OpenAM 16.1.4 发布,三个公告同时发布。
- 2026 年 11 月 8 日:VulnCheck 发布 CVE 记录,GitHub 公告数据库将其列出。
常见问题
这会影响 ForgeRock AM 或其他 OpenAM 分支吗?
公告覆盖 OpenIdentityPlatform OpenAM。它们没有指明 ForgeRock AM 或任何其他分支。如果您运行其他分支,请在依赖本公告之前向其厂商确认是否包含相同修复。
16.1.4 足够吗?
足够。OpenAM 16.1.4 包含三个缺陷的修复,厂商在公告同日发布。请使用 16.1.4 或更高版本。
如果不使用 SAML,我受影响吗?
可能受影响。通知 WebSocket 缺陷影响 OpenAM 14.0.0 至 16.1.3,与是否使用 SAML 无关;自助注册缺陷适用于启用自助注册的所有环境。请检查版本和功能设置。
有公开的漏洞利用吗?
三个缺陷都没有公开的概念验证。公告保留技术细节和利用代码,以便运维人员有时间升级。截至 2026 年 11 月 8 日,它们不在 CISA 的 KEV 目录中。
不升级可以缓解吗?
只能部分缓解。设置 WantAssertionsSigned、禁用自助注册和限制 /openam/notifications 各自关闭一条路径,但都不能修复代码。请尽快升级到 16.1.4。
为什么 CVE 记录在修复版本之后才出现?
厂商于 2026 年 10 月 22 日随 16.1.4 发布公告。VulnCheck 于 2026 年 11 月 8 日分配并发布 CVE 记录,只读取 CVE 源的扫描器这时才能首次标记这些版本。
使用 Ostorlab 发现暴露的 OpenAM 服务器
Ostorlab 的攻击面发现会盘点您面向互联网的主机,让您看到哪些 OpenAM 部署已暴露,并优先升级。它显示暴露的服务,而不是某个实例是否存在漏洞。
参考文献
- OpenIdentityPlatform 公告 GHSA-5c3q-hp86-xjr8,“OpenAM: unauthenticated disclosure of live session tokens via the notification WebSocket”,CVSS v3.1 10.0,影响 14.0.0 至 16.1.3,16.1.4 修复:https://github.com/OpenIdentityPlatform/OpenAM/security/advisories/GHSA-5c3q-hp86-xjr8(2026 年 11 月 8 日查询)
- OpenIdentityPlatform 公告 GHSA-3j2f-qhrc-rjfj,“OpenAM: SAML v2.0 service provider accepts unsigned assertions on some bindings”,CVSS v3.1 9.8,16.1.4 修复:https://github.com/OpenIdentityPlatform/OpenAM/security/advisories/GHSA-3j2f-qhrc-rjfj(2026 年 11 月 8 日查询)
- OpenIdentityPlatform 公告 GHSA-jv8f-m88g-h6mm,“OpenAM: self-registration does not enforce the allowed attribute list”,CVSS v3.1 9.8,16.1.4 修复:https://github.com/OpenIdentityPlatform/OpenAM/security/advisories/GHSA-jv8f-m88g-h6mm(2026 年 11 月 8 日查询)
- CVE-2026-123551 记录,会话令牌泄露,CVSS v4.0 10.0 和 v3.1 10.0:https://www.cve.org/CVERecord?id=CVE-2026-123551(2026 年 11 月 8 日查询)
- CVE-2026-123550 记录,SAML 断言绕过,CVSS v4.0 9.3 和 v3.1 9.8:https://www.cve.org/CVERecord?id=CVE-2026-123550(2026 年 11 月 8 日查询)
- CVE-2026-123549 记录,自助注册提权,CVSS v4.0 9.3 和 v3.1 9.8:https://www.cve.org/CVERecord?id=CVE-2026-123549(2026 年 11 月 8 日查询)
- SAML 缺陷的修复提交,3bf8e61a7e,2026 年 10 月 21 日:https://github.com/OpenIdentityPlatform/OpenAM/commit/3bf8e61a7e(2026 年 11 月 8 日查询)
- 通知 WebSocket 的修复提交,7d6a031c8e,2026 年 10 月 21 日:https://github.com/OpenIdentityPlatform/OpenAM/commit/7d6a031c8e(2026 年 11 月 8 日查询)
- 自助注册的修复提交,4c8a33822a,2026 年 10 月 21 日:https://github.com/OpenIdentityPlatform/OpenAM/commit/4c8a33822a(2026 年 11 月 8 日查询)
- OpenAM 16.1.4 发布,2026 年 10 月 22 日:https://github.com/OpenIdentityPlatform/OpenAM/releases/tag/16.1.4(2026 年 11 月 8 日查询)
- OpenAM 16.1.3 的
SAML2Utils.java,存在漏洞的签名逻辑:https://github.com/OpenIdentityPlatform/OpenAM/blob/16.1.3/openam-federation/openam-federation-library/src/main/java/com/sun/identity/saml2/common/SAML2Utils.java(2026 年 11 月 8 日查询) - OpenAM 16.1.3 的
web.xml,未指定分派器的过滤器映射:https://github.com/OpenIdentityPlatform/OpenAM/blob/16.1.3/openam-server-only/src/main/webapp/WEB-INF/web.xml(2026 年 11 月 8 日查询) - OpenAM 的
ServerVersionResource,未认证的版本端点:https://github.com/OpenIdentityPlatform/OpenAM/blob/16.1.4/openam-core-rest/src/main/java/org/forgerock/openam/core/rest/server/ServerVersionResource.java(2026 年 11 月 8 日查询) - CISA 已知被利用漏洞目录,版本 2026.11.06,没有 OpenAM 条目:https://www.cisa.gov/known-exploited-vulnerabilities-catalog(2026 年 11 月 8 日查询)
- OpenAM 仓库规模,902 个星标和 Docker Hub 474,791 次拉取:https://github.com/OpenIdentityPlatform/OpenAM 和 https://hub.docker.com/r/openidentityplatform/openam(2026 年 11 月 8 日查询)
- 图 1 来源,三个修复提交和 16.1.4 发布:https://github.com/OpenIdentityPlatform/OpenAM/compare/16.1.3...16.1.4(2026 年 11 月 8 日查询)