Nexus Repository Manager 3 修复了一个XXE漏洞XML Externam Entities injection-2020-12-15,从部分开源代码中通过与XXE修复相关的Property、feature找到相关的修复commit a8bd8c7416e3efad004991f0ff808555642fc795,发现其修复方案为

1
2
3
4
5
6
public static void configureValidator(Validator validator)
throws SAXNotRecognizedException, SAXNotSupportedException
{
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
}

一直没有找到漏洞的触发点,从文章Nexus Repository Manager3 Pro XXE 分析(CVE-2020-29436) 中找到对应的SAML触发点

payload
debug 部署包 nexus-3.28.1-01
idea debug

从代码中可以看到nexus在处理SAML时使用的是keycloak组件

1
2
import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;

JAXPValidationUtil.validator逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static Validator validator() throws SAXException, IOException {
SystemPropertiesUtil.ensure();

if (validator == null) {
Schema schema = getSchema();
if (schema == null)
throw logger.nullValueError("schema");

validator = schema.newValidator();
// Do not optimize the following into setProperty(...) && setProperty(...).
// This way if it fails in the first setProperty, it will try the subsequent setProperty anyway
// which it would not due to short-circuiting in case of an && expression.
boolean successful1 = setProperty(validator, XMLConstants.ACCESS_EXTERNAL_DTD, "");
successful1 &= setProperty(validator, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
boolean successful2 = setFeature(validator, feature_disallow_doctype_decl, true);
successful2 &= setFeature(validator, feature_external_general_entities, false);
successful2 &= setFeature(validator, feature_external_parameter_entities, false);
if (! successful1 && ! successful2) {
logger.warn("Cannot disable external access in XML validator");
}
validator.setErrorHandler(new CustomErrorHandler());
}
return validator;
}

其逻辑更新commit为 2020/11/25,9:20 pm 5c2122d36f1a41449ab414e0fcdebc92b04015db

1
2
3
4
5
6
7
8
9
10
11
// Do not optimize the following into setProperty(...) && setProperty(...).
// This way if it fails in the first setProperty, it will try the subsequent setProperty anyway
// which it would not due to short-circuiting in case of an && expression.
boolean successful1 = setProperty(validator, XMLConstants.ACCESS_EXTERNAL_DTD, "");
successful1 &= setProperty(validator, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
boolean successful2 = setFeature(validator, feature_disallow_doctype_decl, true);
successful2 &= setFeature(validator, feature_external_general_entities, false);
successful2 &= setFeature(validator, feature_external_parameter_entities, false);
if (! successful1 && ! successful2) {
logger.warn("Cannot disable external access in XML validator");
}

更新处理XXE漏洞的property及feature。
commit更新前validator throw 带出报错信息debug
keycloadDebug