XXE漏洞安全问题修复与XML外部实体注入预防

发布于: 2019-09-24    浏览: 19433    作者:系统管理员

    近期长沙网站设计公司简界科技有客户的微信商户号接到微信团队发来的消息通知:
     消息1:《异常商户号通知》
     经我司查核,贵方(商户号:1413538102)存在 XXE(XML External Entity Injection)漏洞 问题,为保障相关交易对象的合法权益,确保交易财产的安全,我司将按协议及监管要求对该商户号执行关闭支付权限,如有疑问,贵司可向我司申请技术协助。联系方式为:WePayTS@tencent.com。
     消息2:《XXE漏洞安全通知》
您公司系统的支付回调链接存在XXE漏洞,有被外界非法攻击的风险,请尽快安排技术人员参考微信支付安全实践指引https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=23_5进行更新。

如有疑问,您也可以拨打95017-2或者通过邮箱过邮箱过邮箱过邮箱WePayTS@tencent.com与我们联与我们联与我们联与我们联系,感谢你对微信支付的支持。

   

     根据微信支付开发文档中介绍:XML外部实体注入漏洞(XML External Entity Injection,简称 XXE),该安全问题是由XML组件默认没有禁用外部实体引用导致,非微信支付系统存在漏洞。

XXE漏洞可能带来的危害:可读取任意文件;执行系统命令;探测内网端口;攻击内网网站

XXE的攻击原理:外界攻击者通过模拟回调通知,在回调通知中引入不安全的XML,商户服务器上执行系统命令。

XXE漏洞_长沙网站设计公司_简界科技

       长沙网站设计公司简界科技提出修复方法:

        XXE漏洞需要您在回调处理代码里面解析XML之前,加入禁用实体解析的代码,不同语言设置的内容不同,下面提供了几种主流开发语言的设置指引(您可以根据关键字找到xml解析组件采取对应方法升级):
【PHP】 解析XML代码前加入:
libxml_disable_entity_loader(true); //关键代码
$xml = simplexml_load_string($xmlContent);
......


【JAVA】
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; // catching unsupported features
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
try {
// This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all XML entity attacks are prevented
// Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);

// If you can't completely disable DTDs, then at least do the following:
// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
// JDK7+ - http://xml.org/sax/features/external-general-entities 
FEATURE = "http://xml.org/sax/features/external-general-entities";
dbf.setFeature(FEATURE, false);

// Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
// Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
// JDK7+ - http://xml.org/sax/features/external-parameter-entities 
FEATURE = "http://xml.org/sax/features/external-parameter-entities";
dbf.setFeature(FEATURE, false);

// Disable external DTDs as well
FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
dbf.setFeature(FEATURE, false);

// and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);

// And, per Timothy Morgan: "If for some reason support for inline DOCTYPEs are a requirement, then 
// ensure the entity settings are disabled (as shown above) and beware that SSRF attacks
// (http://cwe.mitre.org/data/definitions/918.html) and denial 
// of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."

// remaining parser logic
} catch (ParserConfigurationException e) {
// This should catch a failed setFeature feature
logger.info("ParserConfigurationException was thrown. The feature '" +
FEATURE + "' is probably not supported by your XML processor.");
}
catch (SAXException e) {
// On Apache, this should be thrown when disallowing DOCTYPE
logger.warning("A DOCTYPE was passed into the XML document");
}
catch (IOException e) {
// XXE that points to a file that doesn't exist
logger.error("IOException occurred, XXE may still possible: " + e.getMessage());
}
DocumentBuilder safebuilder = dbf.newDocumentBuilder();

【.Net】
XmlDocument doc= new XmlDocument();
doc.XmlResolver = null;//关键代码
......

关于XXE漏洞的修复更多介绍请参考微信支付开发文档https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=23_5

XXE漏洞_长沙网站设计公司_简界科技

      接入来介绍下XML外部实体注入详细的预防措施:

      XML外部实体注入(XXE)现在通过点A4成为OWASP Top 10的一部分,它是对解析XML输入的应用程序的一种攻击。
      XXE问题在“ 通用弱点枚举”参考中的ID 611下引用。
当弱配置的XML解析器处理包含对外部实体的引用的不受信任的XML输入时,就会发生此攻击。
这种攻击可能导致泄露机密数据,拒绝服务,服务器端请求伪造(SSRF),从解析器所在的计算机角度进行端口扫描以及其他系统影响。以下指南提供了简要信息以防止此漏洞。
有关XXE的更多信息,请访问XML外部实体(XXE)。


      一般指导
      防止XXE的最安全方法始终是完全禁用DTD(外部实体)。根据解析器,该方法应类似于以下内容:
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
禁用DTD还可以使解析器安全地抵御拒绝服务(DOS)攻击,例如Billion Laughs。如果不可能完全禁用DTD,则必须以特定于每个解析器的方式禁用外部实体和外部文档类型声明。
    下面提供了针对多种语言的详细XXE预防指南以及这些语言中常用的XML解析器。

C / C ++
libxml2的
枚举xmlParserOption不应定义以下选项:

XML_PARSE_NOENT:扩展实体并用替换文本替换它们
XML_PARSE_DTDLOAD:加载外部DTD
注意:
Per:根据这篇文章,从libxml2版本2.9开始,默认情况下,XXE已禁用,如以下补丁所提交的那样。
搜索以下API的用法,以确保没有XML_PARSE_NOENT和XML_PARSE_DTDLOAD在参数中定义:
xmlCtxtReadDoc
xmlCtxtReadFd
xmlCtxtReadFile
xmlCtxtReadIO
xmlCtxtReadMemory
xmlCtxtUseOptions
xmlParseInNodeContext
xmlReadDoc
xmlReadFd
xmlReadFile
xmlReadIO
xmlReadMemory

libxerces-C
使用XercesDOMParser此操作可防止XXE:
XercesDOMParser *parser = new XercesDOMParser;
parser->setCreateEntityReferenceNodes(false);
使用SAXParser,请执行以下操作以防止XXE:

SAXParser* parser = new SAXParser;
parser->setDisableDefaultEntityResolution(true);
使用SAX2XMLReader,这样做可以防止XXE:

SAX2XMLReader* reader = XMLReaderFactory::createXMLReader();
parser->setFeature(XMLUni::fgXercesDisableDefaultEntityResolution, true);

Java的
     使用XML库的Java应用程序特别容易受到XXE的攻击,因为大多数Java XML解析器的默认设置是启用XXE。长沙网站设计公司建议为了安全地使用这些解析器,您必须在使用的解析器中显式禁用XXE。下面介绍如何在最常用的Java XML解析器中禁用XXE。
JAXP DocumentBuilderFactory,SAXParserFactory和DOM4J
DocumentBuilderFactory, SAXParserFactory和DOM4J XML解析器可以使用相同的技术来保护他们免受XXE进行配置。
DocumentBuilderFactory这里仅提供示例。JAXP DocumentBuilderFactory setFeature)方法允许开发人员控制启用或禁用哪些特定于实现的XML处理器功能。
可以在工厂或基础XMLReader setFeature方法上设置功能。
每个XML处理器实现都有自己的功能,这些功能控制如何处理DTD和外部实体。
有关使用突出显示语法的示例代码片段的信息SAXParserFactory,请参见此处。
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; // catching unsupported features
...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = null;
try {
    // This is the PRIMARY defense. If DTDs (doctypes) are disallowed, almost all 
    // XML entity attacks are prevented
    // Xerces 2 only - http://xerces.apache.org/xerces2-j/features.html#disallow-doctype-decl
    FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
    dbf.setFeature(FEATURE, true);


    // If you can't completely disable DTDs, then at least do the following:
    // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-general-entities
    // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-general-entities
    // JDK7+ - http://xml.org/sax/features/external-general-entities
    FEATURE = "http://xml.org/sax/features/external-general-entities";
    dbf.setFeature(FEATURE, false);


    // Xerces 1 - http://xerces.apache.org/xerces-j/features.html#external-parameter-entities
    // Xerces 2 - http://xerces.apache.org/xerces2-j/features.html#external-parameter-entities
    // JDK7+ - http://xml.org/sax/features/external-parameter-entities
    FEATURE = "http://xml.org/sax/features/external-parameter-entities";
    dbf.setFeature(FEATURE, false);

    // Disable external DTDs as well
    FEATURE = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
    dbf.setFeature(FEATURE, false);

    // and these as well, per Timothy Morgan's 2014 paper: "XML Schema, DTD, and Entity Attacks"
    dbf.setXIncludeAware(false);
    dbf.setExpandEntityReferences(false);

    // And, per Timothy Morgan: "If for some reason support for inline DOCTYPEs are a requirement, then
    // ensure the entity settings are disabled (as shown above) and beware that SSRF attacks
    // (http://cwe.mitre.org/data/definitions/918.html) and denial
    // of service attacks (such as billion laughs or decompression bombs via "jar:") are a risk."
    // remaining parser logic
    ...
} catch (ParserConfigurationException e) {
    // This should catch a failed setFeature feature
    logger.info("ParserConfigurationException was thrown. The feature '" + FEATURE 
    + "' is probably not supported by your XML processor.");
    ...
} catch (SAXException e) {
    // On Apache, this should be thrown when disallowing DOCTYPE
    logger.warning("A DOCTYPE was passed into the XML document");
    ...
} catch (IOException e) {
    // XXE that points to a file that doesn't exist
    logger.error("IOException occurred, XXE may still possible: " + e.getMessage());
    ...
}

// Load XML file or stream using a XXE agnostic configured parser...
DocumentBuilder safebuilder = dbf.newDocumentBuilder();
Xerces 1 功能:
不要设置包括外部实体此功能来false。
不要设置包括参数实体此功能来false。
不要设置包括外部的DTD 此功能来false。
Xerces 2 功能:
通过设置禁止内联DTD 此功能来true。
不要设置包括外部实体此功能来false。
不要设置包括参数实体此功能来false。
不要设置包括外部的DTD 此功能来false。
注意:上面的防御措施要求Java 7 update 67,Java 8 update 20或更高版本,因为上述对策DocumentBuilderFactory和SAXParserFactory在较早的Java版本中已被破坏,具体如下:CVE-2014-6517。

XMLInputFactory(StAX解析器)
StAX解析器(例如)XMLInputFactory允许设置各种属性和功能。
要保护Java XMLInputFactory免于XXE,请执行以下操作:
// This disables DTDs entirely for that factory
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); 
// disable external entities
xmlInputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", false);

TransformerFactory
要保护javax.xml.transform.TransformerFactoryXXE,请执行以下操作:
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");


Validator
要保护javax.xml.validation.ValidatorXXE,请执行以下操作:
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
Validator validator = schema.newValidator();
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

SchemaFactory
要保护javax.xml.validation.SchemaFactoryXXE,请执行以下操作:
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
Schema schema = factory.newSchema(Source);


SAXTransformerFactory
要保护javax.xml.transform.sax.SAXTransformerFactoryXXE,请执行以下操作:
SAXTransformerFactory sf = SAXTransformerFactory.newInstance();
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
sf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
sf.newXMLFilter(Source);
注意:要使用以下内容,XMLConstants需要JAXP 1.5,该版本已在7u40和Java 8中添加到Java中:

javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA
javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET


XMLReader的
长沙网站设计公司提示要保护Java org.xml.sax.XMLReader免于XXE,请执行以下操作:
XMLReader reader = XMLReaderFactory.createXMLReader();
reader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// This may not be strictly required as DTDs shouldn't be allowed at all, per previous line.
reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);


XMLReader
要保护Java org.dom4j.io.SAXReader免于XXE,请执行以下操作:
saxReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
saxReader.setFeature("http://xml.org/sax/features/external-general-entities", false);
saxReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
根据测试,如果您缺少其中之一,则仍然容易受到XXE攻击。

SAXBuilder的
要保护Java org.jdom2.input.SAXBuilder免于XXE,请执行以下操作:
SAXBuilder builder = new SAXBuilder();
builder.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);
builder.setFeature("http://xml.org/sax/features/external-general-entities", false);
builder.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
Document doc = builder.build(new File(fileName));


No-op EntityResolver
对于采用的API EntityResolver,您可以通过提供无操作实现来中和XML解析器解析实体的能力:
public final class NoOpEntityResolver implements EntityResolver {
    public InputSource resolveEntity(String publicId, String systemId) {
        return new InputSource(new StringReader(""));
    }
}
// ...
xmlReader.setEntityResolver(new NoOpEntityResolver());
documentBuilder.setEntityResolver(new NoOpEntityResolver());
或更简单地说:
EntityResolver noop = (publicId, systemId) -> new InputSource(new StringReader(""));
xmlReader.setEntityResolver(noop);
documentBuilder.setEntityResolver(noop);


JAXB Unmarshaller
由于javax.xml.bind.Unmarshaller解析XML并不支持禁用XXE的任何标志,因此必须首先通过可配置的安全解析器解析不受信任的XML,然后生成一个源对象,并将该源对象传递给Unmarshaller。例如:
//Disable XXE
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);

//Do unmarshall operation
Source xmlSource = new SAXSource(spf.newSAXParser().getXMLReader(), 
                                new InputSource(new StringReader(xml)));
JAXBContext jc = JAXBContext.newInstance(Object.class);
Unmarshaller um = jc.createUnmarshaller();
um.unmarshal(xmlSource);

Java 8及更高版本
长沙网站设计公司认为由于OpenJDK 8 beta 86中的JDK-8010393,javax.xml.bind.Unmarshaller默认情况下实例是安全的。默认情况下,此处提到的其他类在Java 8中仍然不安全。

XPathExpression
javax.xml.xpath.XPathExpression不能单独安全地配置A ,因此必须首先通过另一个安全的XML解析器来解析不受信任的数据。
例如:
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
df.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
df.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
DocumentBuilder builder = df.newDocumentBuilder();
String result = new XPathExpression().evaluate( builder.parse(
                            new ByteArrayInputStream(xml.getBytes())) );
java.beans.XMLDecoder中
此类中的readObject()方法从根本上讲是不安全的。
它解析的XML不仅要服从XXE,而且该方法还可以用于构造任何Java对象,并执行此处所述的任意代码。
除了信任或正确验证传递给它的输入之外,没有其他方法可以安全地使用此类。
因此,我们强烈建议您完全避免使用此类,并使用本备忘单其他地方所述的安全或正确配置的XML解析器替换该类。

Other XML Parsers
    有许多第三方库可以直接解析XML或通过使用其他库来解析XML。默认情况下,请测试并验证其XML解析器针对XXE是安全的。如果默认情况下解析器不安全,请查找解析器支持的标志以禁用所有可能的外部资源包含,如上面给出的示例。如果没有外部控制,请确保不信任内容先通过安全解析器传递,然后再传递到不安全的第三方解析器,类似于安全解组器的方式。
Spring Framework MVC / OXM XXE漏洞
例如,在Spring OXM和Spring MVC中发现了一些XXE漏洞。Spring框架的以下版本容易受到XXE的攻击:
3.0.0至3.2.3(Spring OXM和Spring MVC)
4.0.0.M1(Spring OXM)
4.0.0.M1-4.0.0.M2(Spring MVC)
还有其他一些问题已在以后修复,因此为了完全解决这些问题,Spring建议您升级到Spring Framework 3.2.8+或4.0.2+。

对于Spring OXM,这是指使用org.springframework.oxm.jaxb.Jaxb2Marshaller。请注意,Spring OXM的CVE特别指出了2种XML解析情况取决于开发人员是否正确,其中2种是Spring的职责,并且已解决此CVE问题。
他们说的是:
开发人员必须处理两种情况:
对于DOMSource,XML已经由用户代码解析,并且该代码负责防止XXE。
对于StAXSource,XMLStreamReader已由用户代码创建,并且该代码负责防止XXE。
Spring修复的问题:
对于SAXSource和StreamSource实例,Spring默认情况下会处理外部实体,从而创建此漏洞。
如果使用的是Spring OXM或Spring MVC的固定版本,下面是使用易受攻击但现在很安全的StreamSource的示例:
import org.springframework.oxm.Jaxb2Marshaller;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
// Must cast return Object to whatever type you are unmarshalling
marshaller.unmarshal(new StreamSource(new StringReader(some_string_containing_XML));
因此,根据Spring OXM CVE编写,以上内容现在很安全。但是,如果要改用DOMSource或StAXSource,则由您决定将这些源配置为对XXE安全。

.NET

.NET中XXE注入的以下信息直接来自Dean Fleming的单元测试Web应用程序。
该Web应用程序涵盖了当前所有受支持的.NET XML解析器,并且针对每个应用程序都有测试用例,以说明何时可以安全地进行XXE注入以及何时不安全。
以前,此信息基于James Jardine的出色的.NET XXE文章。
与如何防止.NET中的XXE和XML拒绝服务相比,它最初提供了比Microsoft较早的文章更新,更详细的信息,但是,Web应用程序涵盖了一些不准确之处。
下表列出了所有受支持的.NET XML解析器及其默认安全级别:

XML Parser Safe by default?
LINQ to XML Yes
XmlDictionaryReader Yes
XmlDocument
...prior to 4.5.2 No
...in versions 4.5.2+ Yes
XmlNodeReader Yes
XmlReader Yes
XmlTextReader
...prior to 4.5.2 No
...in versions 4.5.2+ Yes
XPathNavigator
...prior to 4.5.2 No
...in versions 4.5.2+ Yes
XslCompiledTransform

Ye

s


LINQ转XML
默认情况下,库中的XElement和XDocument对象System.Xml.Linq都不受XXE注入的影响。XElement仅解析XML文件中的元素,因此将完全忽略DTD。默认情况下禁用了XDocument DTD ,并且仅在使用其他不安全的XML解析器构造时才不安全。

XmlDictionaryReader
System.Xml.XmlDictionaryReader默认情况下是安全的,因为当它尝试解析DTD时,编译器会引发异常,指出“ CData元素在XML文档的顶层无效”。如果使用其他不安全的XML解析器构造,它将变得不安全。


XmlDocument
在此之前的.NET Framework版本4.5.2,System.Xml.XmlDocument是不安全的默认。该XmlDocument对象中有一个XmlResolver对象,在4.5.2之前的版本中需要将其设置为null。在版本4.5.2及更高版本中XmlResolver,默认情况下将其设置为null。

以下示例显示了如何使其安全:
 static void LoadXML()
 {
   string xxePayload = "<!DOCTYPE doc [<!ENTITY win SYSTEM 'file:///C:/Users/testdata2.txt'>]>" 
                     + "<doc>&win;</doc>";
   string xml = "<?xml version='1.0' ?>" + xxePayload;


   XmlDocument xmlDoc = new XmlDocument();
   // Setting this to NULL disables DTDs - Its NOT null by default.
   xmlDoc.XmlResolver = null;   
   xmlDoc.LoadXml(xml);
   Console.WriteLine(xmlDoc.InnerText);
   Console.ReadLine();
 }
XmlDocument如果XmlResolver使用默认或不安全设置创建自己的nonnull ,则可能会变得不安全。如果需要启用DTD处理,请参阅MSDN文章中详细说明如何安全地进行处理。

XmlNodeReader
System.Xml.XmlNodeReader 默认情况下,对象是安全的,即使使用不安全的解析器构造或包装在另一个不安全的解析器中,它们也将忽略DTD。

XmlReader
System.Xml.XmlReader 默认情况下,对象是安全的。
默认情况下,将它们设置为在.NET Framework 4.0和更低版本中将其ProhibitDtd属性设置为false,或者DtdProcessing在.NET 4.0和更高版本中将其属性设置为Prohibit。

另外,长沙网站设计公司指出在.NET版本4.5.2后,XmlReaderSettings属于XmlReader具有其XmlResolver默认设置为NULL,它提供了安全性的附加层。
因此,XmlReader只有将两个DtdProcessing属性都设置为Parse且将XmlReaderSetting的s XmlResolver设置为具有默认或不安全设置的nonnull XmlResolver时,对象才会在4.5.2及更高版本中变得不安全。如果需要启用DTD处理,请参阅MSDN文章中详细说明如何安全地进行处理。

在线客服

售前咨询

售后服务

投诉/建议

服务热线
0731-83091505
18874148081