我们的 AI 引擎 Neutron 在加州大学伯克利分校的 CyberGym 基准测试中取得了 97.1% 的成绩。 了解更多

深度解析

深度解析

Keycloak SAML 认证绕过,已在 26.8.2 修复(CVE-2026-117691)

Keycloak 的 SAML 重定向绑定验证的参数与处理的参数不一致,攻击者可冒充任意联合用户登录;已在 26.8.2 中修复。

TL;DR

  • Keycloak 的 SAML HTTP-Redirect 绑定存在缺陷,攻击者把一个未签名的消息和一个已签名的消息一起发送,就能以任意联合用户身份登录。Red Hat 于 2026 年 11 月 5 日发布了 CVE-2026-117691。
  • 通过 SAML 身份代理与外部身份提供者联合登录、启用了签名验证且未要求断言签名的领域会受到影响。Red Hat Build of Keycloak 受影响,Red Hat Single Sign-On 7 不受影响。
  • Red Hat 作为 CVE 编号机构给出 CVSS v3.1 9.1 的评分,并将对自身产品的影响评级定为 Important。截至 2026 年 11 月 5 日,没有公开利用代码,也没有收录到 Cybersecurity and Infrastructure Security Agency(CISA)的 Known Exploited Vulnerabilities(KEV)目录。
  • 请升级到 2026 年 11 月 5 日发布的 Keycloak 26.8.2。检查时 Red Hat 尚未发布勘误;缓解措施及其限制见“如何修复?”。

我受影响吗?

如果您的领域通过 HTTP-Redirect 绑定代理由外部 SAML 身份提供者联合登录,并且运行包含易受攻击检查的 Keycloak 版本,就会受到影响。

  • 领域配置了用于身份代理的 SAML 身份提供者,并且该提供者通过 HTTP-Redirect 绑定返回响应。
  • 该身份提供者的签名验证已启用。Keycloak 在从元数据导入提供者签名证书时会启用签名验证,只有 Keycloak 实际验证签名时,这个绕过才有意义。
  • 身份提供者不要求断言签名。启用“Want Assertions Signed”后,Keycloak 会拒绝未签名的构造断言。
  • Keycloak 版本位于版本表的受影响范围内。

Red Hat 将 Red Hat Single Sign-On 7 列为不受影响,因为其中不存在易受攻击的代码。Red Hat Build of Keycloak 受影响,截至 2026 年 11 月 5 日检查时 Red Hat 尚未发布勘误。keycloak/keycloak 的 main 分支(nightly)在该日期仍包含旧检查;26.8.2 是修复版本。

分支 受影响版本 修复版本
Keycloak 26.8 26.8.0 至 26.8.1 26.8.2(2026-11-05 发布)
Keycloak 26.6 26.6.0 至 26.6.7 26.6.8(2026-11-05 未发布)
Keycloak 26.4 26.4.0 至 26.4.16 26.4.17(2026-11-05 未发布)
Keycloak 26.7、26.5 及更早版本 包含相同检查;未宣布修复版本 迁移到 26.8.2
Red Hat Build of Keycloak 受影响;Red Hat 未列出修复版本 截至 2026-11-05 无勘误
Red Hat Single Sign-On 7 不受影响 不适用

Red Hat 作为 CVE 编号机构,为该缺陷给出 CVSS v3.1 9.1 的评分。向量为 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N。基础严重程度为 Critical,而 Red Hat 对自身产品的影响评级为 Important。截至 2026 年 11 月 5 日检查时,NVD 尚未分析该记录。

Keycloak 维护三个发布分支。一个分支已发布修复,另外两个分支的修复已标记为 26.6.8 和 26.4.17,但在 2026 年 11 月 5 日尚未发布。

请在主机上和每个容器内检查正在运行的版本:

/opt/keycloak/bin/kc.sh --version
docker ps --format '{{.Image}}' | grep -i keycloak
docker exec <container-name> /opt/keycloak/bin/kc.sh --version
kubectl get deploy -A -o jsonpath='{..image}' | tr ' ' '\n' | grep -i keycloak

Red Hat Build of Keycloak 镜像中也包含相同的 kc.sh 二进制文件,因此 docker exec 检查同样适用于 registry.redhat.io/rhbk/keycloak-rhel9。

如何修复?

请升级到 Keycloak 26.8.2(第一个包含修复的上游版本),或在所在分支的向后移植版本发布后升级到该版本。对于容器部署,请先拉取修复后的镜像:

docker pull quay.io/keycloak/keycloak:26.8.2
  1. 重新创建容器。运行中的容器会继续使用旧镜像,直到重新创建。
  2. 对于 ZIP 安装,请从发布页面下载 keycloak-26.8.2.zip。备份配置和数据库,然后替换安装。
  3. 对于 Red Hat Build of Keycloak,Red Hat 在 2026 年 11 月 5 日尚未发布勘误。请关注 Red Hat 公告,并在修复构建发布后更新 rhbk/keycloak-rhel9。
  4. Red Hat Single Sign-On 7 无需针对此 CVE 采取操作。

Red Hat 未给出符合其产品安全标准的缓解措施。如果无法升级,有两种方案可以降低暴露。两者都不是受支持的修复。

  • 要求签名断言:当身份提供者对断言签名时,为该身份提供者启用“Want Assertions Signed”。Keycloak 随后会拒绝未签名的构造断言。这可以在该提供者范围内覆盖 CVE-2026-117691,但会改变信任约定;如果提供者不对断言签名,则无效。
  • 在边界拒绝歧义参数。在 Keycloak 前面的反向代理上,拒绝发往代理端点且包含百分号编码参数名的请求。同时拒绝重复以下任一签名参数的请求:
    • SAMLResponse
    • SAMLRequest
    • RelayState
    • SigAlg
    • Signature

这条规则对应修复逻辑,但代理必须在比较前解码参数名,而且可能破坏使用特殊编码的客户端。请先在仅记录日志的模式下测试。

根本原因是什么?

该缺陷是 Keycloak 处理 SAML 消息时使用的参数名与验证该消息签名时使用的参数名不一致。

Keycloak 的 SAML 身份代理通过 HTTP-Redirect 绑定接收来自外部身份提供者的认证响应。在这种绑定中,整个 SAML 消息放在一个查询参数里,身份提供者对查询字符串而不是 XML 文档签名。

代理入口是 SAMLEndpoint.redirectBinding。它把 samlResponse 声明为 JAX-RS 的 @QueryParam,因此框架在匹配前会解码参数名。当请求同时包含 %53AMLResponse 和 SAMLResponse 时,两者都会解码为 SAMLResponse,方法会收到查询顺序中的第一个值。

// services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java, 26.8.1, lines 182-194
@GET
public Response redirectBinding(@QueryParam(GeneralConstants.SAML_REQUEST_KEY) String samlRequest,
                                @QueryParam(GeneralConstants.SAML_RESPONSE_KEY) String samlResponse,
                                @QueryParam(GeneralConstants.SAML_ARTIFACT_KEY) String samlArt,
                                @QueryParam(GeneralConstants.RELAY_STATE) String relayState)  {
    if (Objects.isNull(samlArt)) {
        return new RedirectBinding().execute(samlRequest, samlResponse, null, relayState, null);
    }
    return new ArtifactBinding().execute(samlRequest, samlResponse, samlArt, relayState, null);
}

验证器通过另一个 API 读取查询。KeycloakUriInfo.getQueryParameters(false) 本应返回原始查询。在 26.8.1 中,它调用 parseQueryParameters(rawQuery, false),这个 false 同时关闭了参数名和值的解码。

// server-spi/src/main/java/org/keycloak/models/KeycloakUriInfo.java, 26.8.1, lines 147-165
public MultivaluedMap<String, String> getQueryParameters(boolean decode) {
    if (decode) {
        return delegate.getQueryParameters(decode);
    }

    MultivaluedMap<String, String> result = new MultivaluedHashMap<>();
    String rawQuery = delegate.getRequestUri().getRawQuery();

    if (rawQuery == null) {
        return result;
    }

    for (Map.Entry<String, List<String>> entry : parseQueryParameters(rawQuery, false).entrySet()) {
        result.put(entry.getKey(), entry.getValue());
    }

    return result;
}

parseQueryParameters 按 & 分割原始查询,只有当 decode 参数为 true 时才解码参数名。使用 false 时,%53AMLResponse 保持为 %53AMLResponse。

// common/src/main/java/org/keycloak/common/util/UriUtils.java, 26.8.1, lines 61-90
String[] nv = param.split("=", 2);
try {
    String name = decode ? URLDecoder.decode(nv[0], "UTF-8") : nv[0];
    String val = nv.length > 1 ? nv[1] : "";
    map.add(name, decode ? URLDecoder.decode(val, "UTF-8") : val);
}

SamlProtocolUtils.verifyRedirectSignature 在这个原始映射中查找 paramKey,也就是 SAMLResponse。百分号编码的副本在该键下不可见,因此 getFirst 返回字面量形式的已签名消息。该方法用这个值、RelayState 和 SigAlg 重建签名串,并验证身份提供者对该串的签名。

// services/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java, 26.8.1, lines 216-251
public static void verifyRedirectSignature(SAMLDocumentHolder documentHolder, KeyLocator locator, UriInfo uriInformation, String paramKey) throws VerificationException {
    MultivaluedMap<String, String> encodedParams = uriInformation.getQueryParameters(false);
    verifyRedirectSignature(documentHolder, locator, encodedParams, paramKey);
}

public static void verifyRedirectSignature(SAMLDocumentHolder documentHolder, KeyLocator locator, MultivaluedMap<String, String> encodedParams, String paramKey) throws VerificationException {
    String request = encodedParams.getFirst(paramKey);
    String algorithm = encodedParams.getFirst(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY);
    String signature = encodedParams.getFirst(GeneralConstants.SAML_SIGNATURE_REQUEST_KEY);
    String relayState = encodedParams.getFirst(GeneralConstants.RELAY_STATE);

    if (request == null) throw new VerificationException("SAM was null");
    if (algorithm == null) throw new VerificationException("SigAlg was null");
    if (signature == null) throw new VerificationException("Signature was null");

    String keyId = getMessageSigningKeyId(documentHolder.getSamlObject());

    StringBuilder rawQueryBuilder = new StringBuilder().append(paramKey).append("=").append(request);
    if (encodedParams.containsKey(GeneralConstants.RELAY_STATE)) {
        rawQueryBuilder.append("&" + GeneralConstants.RELAY_STATE + "=").append(relayState);
    }
    rawQueryBuilder.append("&" + GeneralConstants.SAML_SIG_ALG_REQUEST_KEY + "=").append(algorithm);
    String rawQuery = rawQueryBuilder.toString();

    try {
        byte[] decodedSignature = RedirectBindingUtil.urlBase64Decode(signature);
        String decodedAlgorithm = RedirectBindingUtil.urlDecode(encodedParams.getFirst(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY));
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.getFromXmlMethod(decodedAlgorithm);
        if (!RedirectBindingSignatureUtil.validateRedirectBindingSignature(signatureAlgorithm,
                rawQuery.getBytes(StandardCharsets.UTF_8), decodedSignature, locator, keyId)) {
            throw new VerificationException("Invalid query param signature");
        }
    } catch (Exception e) {
        throw new VerificationException(e);
    }
}

签名有效,但它覆盖的是服务器不会处理的消息。redirectBinding 已经把构造的第一个值传给 execute,而 handleLoginResponse 随后因为查询中存在 SigAlg 和 Signature,把消息视为完全签名。构造的断言本身从未签名。

// services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java, 26.8.1, lines 614-620
boolean signed = AssertionUtil.isSignedElement(assertionElement);
final boolean assertionSignatureNotExistsWhenRequired = config.isWantAssertionsSigned() && !signed;
final boolean signatureNotValid = signed && config.isValidateSignature() && !AssertionUtil.isSignatureValid(assertionElement, getIDPKeyLocator());
final boolean hasNoSignatureWhenRequired = !signed && config.isValidateSignature() && !isMessageFullySigned(holder);

对于重定向绑定,isMessageFullySigned 返回 containsUnencryptedSignature,它只检查查询中是否存在 SigAlg 和 Signature。

// services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java, 26.8.1, lines 898-916
@Override
protected boolean isMessageFullySigned(SAMLDocumentHolder documentHolder) {
    return containsUnencryptedSignature(documentHolder);
}

@Override
protected boolean containsUnencryptedSignature(SAMLDocumentHolder documentHolder) {
    MultivaluedMap<String, String> encodedParams = session.getContext().getUri().getQueryParameters(false);
    String algorithm = encodedParams.getFirst(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY);
    String signature = encodedParams.getFirst(GeneralConstants.SAML_SIGNATURE_REQUEST_KEY);
    return algorithm != null && signature != null;
}

验证器和处理代码对哪个查询参数是 SAMLResponse 的理解不一致,因此签名验证的是一条消息,而代理解析的是另一条消息。

如何被利用?

攻击者需要一条由身份提供者签名的有效重定向绑定消息,以及一个由自己发起的登录会话。然后,攻击者按照把验证与处理分开的顺序发送两条消息。

  1. 攻击者在 Keycloak 领域所代理的外部 SAML 身份提供者处拥有账户。
  2. 攻击者发起代理登录,并获取身份提供者为该账户签发的一条有效签名重定向绑定消息。Red Hat 的描述以注销响应为例。
  3. 攻击者构造一条未签名的 SAML 响应,声称受害者身份,并带上自己发起的登录会话的 Destination 和 InResponseTo。
  4. 攻击者向代理端点发送 GET 请求。构造的响应放在前面,参数名为 %53AMLResponse;合法的签名消息放在后面,参数名为字面量 SAMLResponse。请求保留签名消息的 RelayState、SigAlg 和 Signature。
  5. JAX-RS 把两个参数名都解码为 SAMLResponse,并把第一个值(构造的响应)传给 execute。
  6. verifyRedirectSignature 在不解码参数名的情况下读取原始查询,只找到字面量 SAMLResponse,并对签名消息验证签名。
  7. 构造的响应被解析,未签名的断言因为查询带有 SigAlg 和 Signature 而通过“消息完全签名”检查,Keycloak 以受害者身份登录攻击者。

截至 2026 年 11 月 5 日检查时,没有已知的公开概念验证。这些步骤来自 Red Hat 的 Bugzilla 描述和“根本原因是什么?”中的代码路径。

攻击如何展开?

攻击者把未签名断言与签名消息配对,使 Keycloak 验证签名消息却处理未签名消息。

flowchart TD A["拥有 IdP 账户的攻击者
发起代理登录"] --> B["获取一条签名的
重定向绑定消息"] --> C["先发送构造的消息,
再发送签名的 SAMLResponse"] --> D["服务器验证签名消息
却处理构造的消息"] --> E["不检查签名值是否
就是被处理的值"] --> F["以受害者身份登录"]

攻击者能做什么?

完成绕过的攻击者会以构造断言中所指的联合用户身份登录,并获得该用户的角色和数据。

绕过需要同时满足以下条件:

  • 外部身份提供者的账户,攻击者用它获取一条有效的签名重定向绑定消息。
  • 攻击者发起的代理登录会话,使构造的响应带有匹配的 Destination 和 InResponseTo。
  • 通过 HTTP-Redirect 绑定代理由该身份提供者联合登录的领域。
  • 签名验证开启且“Want Assertions Signed”关闭的常见配置。
  • 能够通过网络访问 Keycloak 代理端点。

Red Hat 的声明说,成功利用后攻击者可以“以任意用户身份登录,并在未经授权的情况下访问其角色和数据”。影响取决于受害者的角色,因此如果受害者在连接的应用中拥有管理权限,攻击者也会继承该权限。CVSS 向量把可用性影响设为 None,公告也没有描述代码执行或拒绝服务。

为什么修复有效?

修复做了三件事。它让签名验证使用与处理路径相同的解码参数名。它拒绝重复的 SAML 参数。它比较签名值与正在处理的值。

共享 URI 解析器现在解码参数名,同时保持参数值编码:

--- a/server-spi/src/main/java/org/keycloak/models/KeycloakUriInfo.java
+++ b/server-spi/src/main/java/org/keycloak/models/KeycloakUriInfo.java
@@
-        for (Map.Entry<String, List<String>> entry : parseQueryParameters(rawQuery, false).entrySet()) {
+        for (Map.Entry<String, List<String>> entry : parseQueryParameters(rawQuery, true, false).entrySet()) {

名称解码后,%53AMLResponse 和 SAMLResponse 在原始视图中都会出现在 SAMLResponse 下,新的重复检查会拒绝该请求:

--- a/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
+++ b/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java
@@
+    public static void rejectRepeatedRedirectParameters(MultivaluedMap<String, String> encodedParams) throws VerificationException {
+        for (String name : REDIRECT_SIGNATURE_PARAMETERS) {
+            List<String> values = encodedParams.get(name);
+            if (values != null && values.size() > 1) {
+                throw new VerificationException("Query parameter " + name + " is present more than once");
+            }
+        }
+    }
+
+    private static void verifySignedValueIsProcessed(MultivaluedMap<String, String> encodedParams, String paramKey, String processedValue) throws VerificationException {
+        String signedValue = encodedParams.getFirst(paramKey);
+        String decodedSignedValue;
+        try {
+            decodedSignedValue = signedValue == null ? null : RedirectBindingUtil.urlDecode(signedValue);
+        } catch (IOException | IllegalArgumentException e) {
+            throw new VerificationException("Invalid encoding of query parameter " + paramKey, e);
+        }
+        if (!Objects.equals(decodedSignedValue, processedValue)) {
+            throw new VerificationException("Query parameter " + paramKey + " being processed is not the signed one");
+        }
+    }

端点现在把正在处理的消息传给验证器:

--- a/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
+++ b/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java
@@
-                    verifySignature(GeneralConstants.SAML_RESPONSE_KEY, holder);
+                    verifySignature(GeneralConstants.SAML_RESPONSE_KEY, holder, samlResponse, relayState);

verifySignedValueIsProcessed 解码签名值,并与传给 execute 的值比较。即使绕过重复检查,与处理值不同的签名消息也会失败。RelayState 也接受同样的比较。rejectRepeatedRedirectParameters 还会从 basicChecks 和 SamlService 的重定向绑定中调用,因此两个重定向端点都会在处理前拒绝重复参数。

该提交修复了它涉及的两处重定向绑定检查:SAMLEndpoint 中的代理端点和 SamlService 中的身份提供者端点。POST 和 artifact 绑定不以这种方式读取查询字符串,因此没有改动。

如何检查是否已遭入侵?

截至 2026 年 11 月 5 日,没有针对 CVE-2026-117691 的公开入侵指标。

公开描述给出了一条线索:发往代理端点的请求中出现百分号编码的 SAML 参数名。如果反向代理保留查询字符串,请搜索访问日志:

grep -iE '[?&](%[0-9a-f]{2})+(amlresponse|amlrequest|elaystate|igalg|ignature)=' /var/log/nginx/access.log

如果日志存储的是解码后的查询字符串,请改为查找同一个请求中出现两个 SAMLResponse 参数:

grep -iE '[?&]samlresponse=[^&]*&.*[?&]samlresponse=' /var/log/nginx/access.log

命中只是线索,不是证据:合法客户端也可能对参数名进行百分号编码或发送重复参数。请用完整请求和身份提供者日志确认。如果未记录查询字符串,失败的尝试可能不留痕迹,因此没有命中并不证明没有尝试。

时间线

  • 2026-10-26:向 Red Hat 报告。
  • 2026-11-05:发布 CVE-2026-117691。
  • 2026-11-05:修复提交 cbda2bfd35 进入 keycloak/keycloak。
  • 2026-11-05:发布 Keycloak 26.8.2。
  • 2026-11-05:检查时没有公开概念验证,也没有 CISA KEV 条目。

从报告到公开披露经过了 10 天。修复提交在 CVE 记录发布后 1 小时 52 分钟到达,26.8.2 版本随后在 41 分钟后发布。

报告保密了 10 天,随后修复和发布在同一天完成
图 1:从报告到公开披露经过 10 天,随后修复和 26.8.2 版本在同一天完成。来源:CVE 记录、keycloak/keycloak 提交 cbda2bfd35 和 26.8.2 版本,2026 年 11 月 5 日检查

常见问题

当 Keycloak 作为 SAML 身份提供者而不是代理时,是否受影响?

账户接管的影响位于代理路径,即 Keycloak 消费来自外部身份提供者的响应。同一个提交还加强了 SamlService 中身份提供者端点的重定向绑定检查,因此修复覆盖两条路径。

攻击者需要 Keycloak 账户吗?

不需要。由于不需要 Keycloak 账户,Red Hat 将该攻击评为无需特权。但攻击者确实需要外部身份提供者的账户,以获取一条有效的签名重定向绑定消息。

启用“Want Assertions Signed”就是修复吗?

它会阻止未签名的构造断言,因此可以降低暴露。但它不能替代 26.8.2,因为它改变了与身份提供者的信任约定,而且只有在提供者对断言签名时才有效。

有公开利用代码吗?

截至 2026 年 11 月 5 日,没有已知的公开概念验证或在野利用。CISA 的 Authorized Data Publisher(ADP)记录列出 Exploitation: none,该 CVE 也不在 KEV 目录中。

哪个版本修复了该问题?

Keycloak 26.8.2,于 2026 年 11 月 5 日发布。26.6.8 和 26.4.17 向后移植已标记,但检查时尚未发布,Red Hat Build of Keycloak 也没有勘误。

Red Hat Single Sign-On 7 受影响吗?

不受影响。Red Hat 将其列为不受影响,因为其中不存在易受攻击的代码。

参考文献

  • Red Hat,“CVE-2026-117691”公告,https://access.redhat.com/security/cve/CVE-2026-117691(2026 年 11 月 5 日检查)。
  • CVE Program,“CVE-2026-117691”记录,https://www.cve.org/CVERecord?id=CVE-2026-117691(2026 年 11 月 5 日检查)。
  • Red Hat Bugzilla,“CVE-2026-117691 keycloak-services: SAML redirect binding signature bypass via percent-encoded parameter names”,https://bugzilla.redhat.com/show_bug.cgi?id=2561977(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,“Verify the SAML redirect binding message that is processed”,提交 cbda2bfd35e2eb182942996832b819c35780b121,https://github.com/keycloak/keycloak/commit/cbda2bfd35e2eb182942996832b819c35780b121(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,26.8.2 版本,https://github.com/keycloak/keycloak/releases/tag/26.8.2(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,26.8.1 的 SamlProtocolUtils.java,https://github.com/keycloak/keycloak/blob/26.8.1/services/src/main/java/org/keycloak/protocol/saml/SamlProtocolUtils.java(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,26.8.1 的 SAMLEndpoint.java,https://github.com/keycloak/keycloak/blob/26.8.1/services/src/main/java/org/keycloak/broker/saml/SAMLEndpoint.java(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,26.8.1 的 KeycloakUriInfo.java,https://github.com/keycloak/keycloak/blob/26.8.1/server-spi/src/main/java/org/keycloak/models/KeycloakUriInfo.java(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,26.8.1 的 UriUtils.java,https://github.com/keycloak/keycloak/blob/26.8.1/common/src/main/java/org/keycloak/common/util/UriUtils.java(2026 年 11 月 5 日检查)。
  • keycloak/keycloak,“CVE-2026-117691 SAML redirect binding signature bypass via percent-encoded parameter name”,issue 54714,https://github.com/keycloak/keycloak/issues/54714(2026 年 11 月 5 日检查)。
  • Keycloak,“Configuring a SAML identity provider”,服务器管理指南,https://www.keycloak.org/docs/26.8.1/server_admin/#_identity_broker_saml(2026 年 11 月 5 日检查)。
  • Cybersecurity and Infrastructure Security Agency,Known Exploited Vulnerabilities 目录,https://www.cisa.gov/known-exploited-vulnerabilities-catalog(2026 年 11 月 5 日检查)。
  • National Vulnerability Database,“CVE-2026-117691”,https://nvd.nist.gov/vuln/detail/CVE-2026-117691(2026 年 11 月 5 日检查)。