XML External Entity Prevention Cheat Sheet / XML外部实体预防技巧表¶
Introduction / 介绍¶
XML External Entity (XXE) injection occurs when an XML processor resolves an external entity from untrusted input. This can expose local files, cause server-side request forgery (SSRF), or exhaust resources. CWE-611 describes the weakness; this cheat sheet gives parser-specific controls to prevent it.
当XML处理器从不受信任的输入中解析外部实体时,就会发生XML外部实体(XXE)注入。这可能导致暴露本地文件、引起服务器端请求伪造(SSRF)或耗尽资源。CWE-611 描述了这种弱点;此技巧表提供了针对解析器的特定控制措施以防止其发生。
General Guidance / 一般指导¶
Disable document type definitions (DTDs) whenever possible. Reject DOCTYPE declarations if the parser supports it. If your application needs DTDs, disable external entity resolution and external DTD loading, and limit entity expansion.
尽可能禁用文档类型定义(DTDs)。 如果解析器支持,则拒绝DOCTYPE声明。如果您的应用程序需要DTDs,请禁用外部实体解析和外部DTD加载,并限制实体扩展。
- Keep XInclude disabled unless explicitly required; it can load resources independently of DTDs.
中文:除非明确需要,否则请保持XInclude禁用;它可以独立于DTDs加载资源。 - Restrict external access during schema validation and style sheet processing as well as XML parsing.
中文:在模式验证、样式表处理以及XML解析期间限制外部访问。 - Treat an unsupported security setting as a configuration failure. Do not continue processing untrusted XML with partial hardening.
中文:将不受支持的安全设置视为配置失败。不要在部分加固的情况下继续处理不受信任的XML。
Controls and defaults vary by parser; see the language-specific guidance below and, for Java, the JAXP Security Guide. Preventing XXE does not prevent every XML denial-of-service attack. See the XML Security Cheat Sheet for entity expansion and other XML resource risks.
控制和默认值因解析器而异;请参阅以下特定于语言的指导,以及Java的JAXP安全指南。防止XXE并不能防止所有XML拒绝服务攻击。请参阅XML安全技巧表以了解实体扩展和其他XML资源风险。
C/C++¶
libxml2¶
The Enum xmlParserOption should not have the following options defined:
枚举xmlParserOption不应定义以下选项:
XML_PARSE_NOENT: Expands entities and substitutes them with replacement text
中文:XML_PARSE_NOENT:展开实体并用替换文本替换XML_PARSE_DTDLOAD: Load the external DTD
中文:XML_PARSE_DTDLOAD:加载外部DTD
Note:
注意:
Per: According to this post, starting with libxml2 version 2.9, XXE has been disabled by default as committed by the following patch.
根据这篇帖子,从libxml2版本2.9开始,XXE默认已被禁用,这是由以下补丁实现的。
Search whether the following APIs are being used and make sure there is no XML_PARSE_NOENT and XML_PARSE_DTDLOAD defined in the parameters:
搜索以下API是否被使用,并确保参数中没有定义XML_PARSE_NOENT和XML_PARSE_DTDLOAD:
xmlCtxtReadDocxmlCtxtReadFdxmlCtxtReadFilexmlCtxtReadIOxmlCtxtReadMemoryxmlCtxtUseOptionsxmlParseInNodeContextxmlReadDocxmlReadFdxmlReadFilexmlReadIOxmlReadMemory
libxerces-c¶
Use of XercesDOMParser do this to prevent XXE:
使用XercesDOMParser时,这样做可以防止XXE攻击:
XercesDOMParser *parser = new XercesDOMParser;
parser->setCreateEntityReferenceNodes(true);
parser->setDisableDefaultEntityResolution(true);
Use of SAXParser, do this to prevent XXE:
使用SAXParser时,这样做可以防止XXE攻击:
SAXParser* parser = new SAXParser;
parser->setDisableDefaultEntityResolution(true);
For SAX2XMLReader, configure the reader that will parse the document. The Xerces-C++ feature documentation describes fgXercesDisableDefaultEntityResolution: it prevents fallback resolution when resolveEntity returns NULL. A custom resolver must also reject unapproved resources.
对于SAX2XMLReader,配置将解析文档的读取器。Xerces-C++功能文档中的fgXercesDisableDefaultEntityResolution描述了:它防止在resolveEntity返回NULL时回退解析。自定义解析器还必须拒绝未经批准的资源。
SAX2XMLReader* reader = XMLReaderFactory::createXMLReader();
reader->setFeature(XMLUni::fgXercesDisableDefaultEntityResolution, true);
ColdFusion¶
Per this blog post, both Adobe ColdFusion and Lucee have built-in mechanisms to disable support for external XML entities.
根据这篇博客文章,Adobe ColdFusion和Lucee都内置了禁用对外部XML实体支持的机制。
Adobe ColdFusion¶
As of ColdFusion 2018 Update 14 and ColdFusion 2021 Update 4, all native ColdFusion functions that process XML have a XML parser argument that disables support for external XML entities. Since there is no global setting that disables external entities, developers must ensure that every XML function call uses the correct security options.
从ColdFusion 2018 Update 14和ColdFusion 2021 Update 4开始,所有处理XML的本地ColdFusion函数都有一个XML解析器参数,该参数可以禁用对外部XML实体的支持。由于没有全局设置可以禁用外部实体,开发者必须确保每个XML函数调用都使用正确的安全选项。
From the documentation for the XmlParse() function, you can disable XXE with the code below:
从XmlParse()函数的文档中,您可以使用以下代码禁用XXE:
<cfset parseroptions = structnew()>
<cfset parseroptions.ALLOWEXTERNALENTITIES = false>
<cfscript>
a = XmlParse("xml.xml", false, parseroptions);
writeDump(a);
</cfscript>
You can use the "parseroptions" structure shown above as an argument to secure other functions that process XML as well, such as:
您可以将上面显示的"parseroptions"结构作为参数传递给其他处理XML的函数,例如:
XxmlSearch(xmldoc, xpath,parseroptions);
XmlTransform(xmldoc,xslt,parseroptions);
isXML(xmldoc,parseroptions);
Lucee¶
As of Lucee 5.3.4.51 and later, you can disable support for XML external entities by adding the following to your Application.cfc:
从Lucee 5.3.4.51版本开始,您可以通过在Application.cfc中添加以下内容来禁用XML外部实体的支持:
this.xmlFeatures = {
externalGeneralEntities: false,
secure: true,
disallowDoctypeDecl: true
};
Support for external XML entities is disabled by default as of Lucee 5.4.2.10 and Lucee 6.0.0.514.
自Lucee 5.4.2.10和Lucee 6.0.0.514版本起,默认禁用对外部XML实体的支持。
Java¶
The examples below use the built-in Java API for XML Processing (JAXP) implementations on Java 9 or later. newDefaultInstance() (newDefaultFactory() for StAX) selects the built-in implementation instead of a provider selected through the JAXP lookup mechanism. For other providers, see implementation differences.
These are illustrative configuration fragments. The application opens and closes the input streams, supplies trusted schemas and style sheets, and handles exceptions. Stop processing if any required security setting fails; do not catch the exception and continue parsing. Pass streams rather than untrusted filenames or URLs: external-entity controls do not restrict access to the initial resource passed directly to a parsing or processing API.
Secure configuration by API¶
| API | Recommended approach / 推荐方法 |
|---|---|
DocumentBuilderFactory |
Reject DOCTYPE declarations before building a document tree 在构建文档树之前拒绝DOCTYPE声明 |
SAXParserFactory / XMLReader |
Reject DOCTYPE declarations; parse through the configured reader 拒绝DOCTYPE声明;通过配置的读取器进行解析 |
XMLInputFactory |
Disable DTD processing and external entities 禁用 DTD 处理和外部实体 |
TransformerFactory |
Deny external access before compiling the style sheet 在编译样式表之前拒绝外部访问 |
SchemaFactory / Validator |
Deny external access during compilation and validation 在编译和验证期间拒绝外部访问 |
XPath |
Evaluate against a document parsed with a hardened builder 使用强化构建器解析的文档进行评估 |
Unmarshaller |
Supply a hardened StAX reader 提供一个加固的StAX读取器 |
DocumentBuilderFactory (DOM)¶
For Document Object Model (DOM) parsing, reject DOCTYPE declarations and leave XInclude disabled.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(untrustedStream);
setExpandEntityReferences(false) controls the representation of entity references in the tree. Do not use it as a substitute for blocking external resources.
SAXParserFactory and XMLReader¶
For Simple API for XML (SAX) parsing, reject DOCTYPE declarations on the factory before creating the reader.
对于简单的XML解析API(SAX),在创建读取器之前,在工厂中拒绝DOCTYPE声明。
SAXParserFactory spf = SAXParserFactory.newDefaultInstance();
spf.setNamespaceAware(true);
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
XMLReader reader = spf.newSAXParser().getXMLReader();
reader.setContentHandler(handler); // application's SAX content handler
reader.parse(new InputSource(untrustedStream));
XMLInputFactory (StAX) / XMLInputFactory(StAX)¶
For Streaming API for XML (StAX), set both DTD and external-entity properties. DTD processing defaults to enabled; the external-entity default is unspecified.
对于XML流式API(StAX),设置DTD和外部实体属性链接。DTD处理默认为启用;外部实体的默认值未指定。
XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xif.setXMLResolver((publicId, systemId, baseURI, namespace) -> {
throw new XMLStreamException("External references are not allowed");
});
XMLStreamReader xsr = xif.createXMLStreamReader(untrustedStream);
Disabling DTD processing does not necessarily reject the DOCTYPE declaration. StAX does not support FEATURE_SECURE_PROCESSING; use the provider's processing limits when DTDs are required.
禁用DTD处理并不一定拒绝DOCTYPE声明。StAX不支持FEATURE_SECURE_PROCESSING;当需要DTD时,使用提供者的处理限制。
TransformerFactory (XSLT) / TransformerFactory(XSLT)¶
XSL Transformations (XSLT) can load resources through style sheet imports, includes and document(), independently of external entities. For a trusted application-owned style sheet that needs no external resources, set both external-access restrictions before compilation:
XSL转换(XSLT)可以通过样式表导入、包含和document()加载资源,独立于外部实体。对于不需要外部资源的可信应用程序拥有的样式表,在编译前设置外部访问限制:
TransformerFactory factory = TransformerFactory.newDefaultInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
Transformer transformer =
factory.newTransformer(new StreamSource(trustedStylesheetStream));
transformer.transform(new StreamSource(untrustedStream), result);
This configuration limits internal entity expansion but is not a sandbox for untrusted style sheets. Choose the style sheet in application code; do not trust a style sheet reference supplied by the input document. For other providers or required dependencies, apply the resource policy below.
此配置限制了内部实体扩展,但不是不受信任样式表的沙盒。在应用程序代码中选择样式表;不要信任输入文档提供的样式表引用。对于其他提供者或必需的依赖项,应用以下资源策略。
SchemaFactory and Validator / SchemaFactory和Validator¶
Schema compilation and validation can each load external resources. For a trusted application-owned schema that needs no external resources, restrict access on the factory before compiling the schema; these restrictions also apply during validation:
模式编译和验证都可以加载外部资源。对于不需要外部资源的受信任应用程序拥有的模式,在编译模式之前在工厂上限制访问;这些限制也适用于验证期间:
SchemaFactory sf = SchemaFactory.newDefaultInstance();
sf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
sf.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
sf.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
Schema schema = sf.newSchema(new StreamSource(trustedSchemaStream));
Validator validator = schema.newValidator();
validator.validate(new StreamSource(untrustedStream));
If you install a resolver, configure it on the factory and each validator: validators do not inherit the factory's resolver. The same applies to ValidatorHandler.
如果您安装了解析器,请在工厂以及每个验证器上配置它:验证器不会继承工厂的解析器。同样适用于ValidatorHandler。
XPath¶
Avoid the InputSource overloads of XPath.evaluate, which parse the document internally. Use the hardened DOM builder and evaluate against the resulting document:
避免使用XPath.evaluate的InputSource重载(https://docs.oracle.com/en/java/javase/25/docs/api/java.xml/javax/xml/xpath/XPath.html#evaluate(java.lang.String,org.xml.sax.InputSource)),这些重载会内部解析文档。使用加固的DOM构建器并针对生成的文档进行评估:
Document doc = builder.parse(untrustedStream);
XPath xpath = XPathFactory.newDefaultInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//user/name", doc, XPathConstants.NODESET);
JAXB Unmarshaller¶
For Java Architecture for XML Binding (JAXB), pass the reader from the StAX example to Unmarshaller.unmarshal. Passing raw XML instead delegates parser configuration to the JAXB provider.
对于Java Architecture for XML Binding (JAXB),将StAX示例中的读取器传递给Unmarshaller.unmarshal(https://jakarta.ee/specifications/xml-binding/4.0/apidocs/jakarta.xml.bind/jakarta/xml/bind/Unmarshaller.html#unmarshal(javax.xml.stream.XMLStreamReader))。传递原始XML会将解析器配置委托给JAXB提供者。
Object result = jaxbContext.createUnmarshaller().unmarshal(xsr);
Other providers and required DTDs / 其他提供者和所需的DTD¶
newInstance() can select a third-party provider whose settings differ. Verify the provider's documented controls and fail if a required setting is unsupported. Boolean features use setFeature; external-access properties use setAttribute on a DOM factory and setProperty on a SAX parser or reader.
newInstance()可以选择一个设置不同的第三方提供者。验证提供者的文档化控制,如果所需的设置不受支持则失败。布尔功能使用setFeature;外部访问属性使用DOM工厂上的setAttribute和SAX解析器或读取器上的setProperty。
If internal DTDs are required, install an EntityResolver on the DOM builder or SAX reader that throws SAXException for external references. Returning null delegates resolution to the parser. Set these Xerces/SAX features to false instead of rejecting DOCTYPE:
如果需要内部 DTD,在 DOM 构建器或 SAX 读取器上安装一个抛出 SAXException 的 EntityResolver 以处理外部引用。返回 null 将解析委托给解析器。将以下 Xerces/SAX 功能 设置为 false 而不是拒绝 DOCTYPE:
http://xml.org/sax/features/external-general-entitieshttp://xml.org/sax/features/external-parameter-entitieshttp://apache.org/xml/features/nonvalidating/load-external-dtd
Keep XInclude disabled. The last feature only controls non-validating parsing; DTD validation needs an explicit policy for any required external DTD. Set applicable ACCESS_EXTERNAL_* properties to "" when supported. A resolver does not limit internal entity expansion: enable FEATURE_SECURE_PROCESSING where supported and configure the provider's processing limits. Secure processing alone is not a portable replacement for external-access restrictions.
保持 XInclude 禁用。最后一个功能仅控制非验证解析;DTD 验证需要任何所需外部 DTD 的显式策略。当支持时,将适用的 ACCESS_EXTERNAL_* 属性设置为 ""。解析器不会限制内部实体扩展:在支持的情况下启用 FEATURE_SECURE_PROCESSING 并配置提供者的处理限制。仅安全处理不能作为外部访问限制的可移植替代方案。
When using a SAX resolver, call reader.parse(...) directly. SAXParser.parse(source, DefaultHandler) replaces the reader's resolver with the supplied handler.
当使用 SAX 解析器时,直接调用 reader.parse(...)。SAXParser.parse(source, DefaultHandler) 替换了读取器的解析器(GitHub)
External resources for transformations and validation / 用于转换和验证的外部资源¶
For other transformation or validation providers, supply XML, schemas and style sheets through a SAXSource with a hardened, namespace-aware XMLReader. Separately install a rejecting URIResolver for transformations or LSResourceResolver for schemas. The input parser's settings do not control style sheet or schema dependencies.
对于其他转换或验证提供者,通过一个具有加固的、命名空间感知的 XMLReader 的 SAXSource 提供 XML、模式表和样式表。单独安装拒绝 URIResolver 的转换或 LSResourceResolver 的模式。输入解析器的设置不控制样式表或模式依赖项。
When external dependencies are required, use a catalog with RESOLVE=strict to map approved identifiers to local resources, or an allowlisting resolver. Reject unapproved identifiers; returning null delegates to default resolution. External-access properties restrict protocols, not individual resources: allowing https is not a resource allowlist. Resources returned by your resolver remain your responsibility.
当需要外部依赖项时,使用具有 RESOLVE=strict 的 目录 将批准的标识符映射到本地资源,或使用允许列表解析器。拒绝未经批准的标识符;返回 null 将委托给默认解析。外部访问属性限制协议,而不是单个资源:允许 https 不是一个资源允许列表。解析器返回的资源仍然是您的责任。
Apply the policy before compilation and during processing. Set the URIResolver on the transformer factory before newTransformer; transformers use it by default. For validation, install the resolver on the factory and every validator as described above.
在编译和处理期间应用策略。在 newTransformer 之前将 URIResolver 设置在转换器工厂上;转换器默认使用它。对于验证,按照上述描述在工厂和每个验证器上安装解析器。
Parsers that wrap a JAXP parser / 包装 JAXP 解析器的解析器¶
Supply wrappers with a hardened parser and check whether they replace its resolver:
| Library / 库 | Configuration / 配置 |
|---|---|
| dom4j | Supply the reader with SAXReader.setXMLReader and set the rejecting resolver with SAXReader.setEntityResolver; dom4j replaces the reader's resolver使用 SAXReader.setXMLReader 方法提供读取器,并通过 SAXReader.setEntityResolver 设置拒绝解析器;dom4j 替换了读取器的解析器 |
| JDOM | Supply the reader through SAXBuilder(XMLReaderJDOMFactory)通过 SAXBuilder(XMLReaderJDOMFactory)向读者提供信息 |
| Commons Digester | Supply a hardened reader and call Digester.setEntityResolver before parsing; Digester replaces the reader's resolver提供加固的读取器,并在解析之前调用 Digester.setEntityResolver;Digester替换读取器的解析器 |
Oracle DOM Parser¶
For Oracle XML Developer's Kit (oracle.xml.parser.v2), call setSecureProcessing() on the DOM or SAX parser. It disables entity resolution and limits expansion. On its JAXP binding, enable FEATURE_SECURE_PROCESSING.
java.beans.XMLDecoder¶
Do not use XMLDecoder with untrusted input. Blocking external entities does not remove its deserialization risk.
Secure JAXP factory sources¶
Apache Commons Secure XML provides preconfigured factories. Check its threat model for supported runtimes and limits. Its protections do not cover URIs passed directly to parsing APIs, parsers created outside the library, or untrusted resources your resolver chooses to supply. Do not loosen its reserved security settings.
.NET¶
Up-to-date information for XXE injection in .NET is taken directly from the web application of unit tests by Dean Fleming, which covers all currently supported .NET XML parsers, and has test cases that demonstrate when they are safe from XXE injection and when they are not, but these tests are only with injection from file and not direct DTD (used by DoS attacks).
For DoS attacks using a direct DTD (such as the Billion laughs attack), a separate testing application from Josh Grossman at Bounce Security has been created to verify that .NET >=4.5.2 is safe from these attacks.
Previously, this information was based on some older articles which may not be 100% accurate including:
- James Jardine's excellent .NET XXE article.
- Guidance from Microsoft on how to prevent XXE and XML Denial of Service in .NET.
Overview of .NET Parser Safety Levels¶
Below is an overview of all supported .NET XML parsers and their default safety levels. More details about each parser are included below.
XDocument (LINQ to XML) default safety levels¶
This parser is protected from external entities at .NET Framework version 4.5.2 and protected from Billion Laughs at version 4.5.2 or greater, but it is uncertain if this parser is protected from Billion Laughs before version 4.5.2.
此解析器在.NET Framework 4.5.2版本中受到外部实体保护,并在4.5.2或更高版本中受到Billion Laughs保护,但无法确定在4.5.2版本之前此解析器是否受到Billion Laughs保护。
XmlDocument, XmlTextReader, XPathNavigator default safety levels / XmlDocument、XmlTextReader、XPathNavigator默认安全级别¶
These parsers are vulnerable to external entity attacks and Billion Laughs at versions below version 4.5.2 but protected at versions equal or greater than 4.5.2.
这些解析器在版本低于4.5.2时易受外部实体攻击和Billion Laughs攻击,但在版本等于或高于4.5.2时受到保护。
XmlDictionaryReader, XmlNodeReader, XmlReader default safety levels / XmlDictionaryReader、XmlNodeReader、XmlReader默认安全级别¶
These parsers are not vulnerable to external entity attacks or Billion Laughs before or after version 4.5.2. Also, at or greater than versions ≥4.5.2, these libraries won't even process the in-line DTD by default. Even if you change the default to allow processing a DTD, if a DoS attempt is performed an exception will still be thrown as documented above.
这些解析器在版本4.5.2之前或之后均不受外部实体攻击或Billion Laughs攻击。此外,在或高于4.5.2的版本中,这些库默认甚至不会处理内联DTD。即使您将默认值更改为允许处理DTD,如果执行DoS攻击,仍会抛出异常,如上所述。
ASP.NET¶
ASP.NET applications ≥ .NET 4.5.2 must also ensure setting the <httpRuntime targetFramework="..." /> in their Web.config to ≥4.5.2 or risk being vulnerable regardless of the actual .NET version. Omitting this tag will also result in unsafe-by-default behavior.
版本≥.NET 4.5.2的ASP.NET应用程序还必须确保在它们的Web.config中设置<httpRuntime targetFramework="..." />为≥4.5.2,否则无论实际的.NET版本如何,都存在易受攻击的风险。省略此标记也会导致默认不安全的行为。
For the purpose of understanding the version thresholds above, the effective .NET Framework version for an ASP.NET application is either the .NET version the application was built with or the httpRuntime's targetFramework (Web.config), whichever is lower.
为了理解上述版本阈值,ASP.NET应用程序的有效.NET Framework版本是应用程序构建时使用的.NET版本或httpRuntime的targetFramework(Web.config),取较低者。
This configuration tag should not be confused with a similar configuration tag: <compilation targetFramework="..." /> or the assemblies / projects targetFramework, which are not sufficient for achieving secure-by-default behavior as described above.
LINQ to XML¶
Both the XElement and XDocument objects in the System.Xml.Linq library are safe from XXE injection from external file and DoS attack by default. XElement parses only the elements within the XML file, so DTDs are ignored altogether. XDocument has XmlResolver disabled by default so it's safe from SSRF. While DTDs are enabled by default, from Framework versions ≥4.5.2, it is not vulnerable to DoS as noted but it may be vulnerable in earlier Framework versions. For more information, see Microsoft's guidance on how to prevent XXE and XML Denial of Service in .NET
XmlDictionaryReader¶
System.Xml.XmlDictionaryReader is safe by default, as when it attempts to parse the DTD, the compiler throws an exception saying that "CData elements not valid at top level of an XML document". It becomes unsafe if constructed with a different unsafe XML parser.
XmlDocument¶
Prior to .NET Framework version 4.5.2, System.Xml.XmlDocument is unsafe by default. The XmlDocument object has an XmlResolver object within it that needs to be set to null in versions prior to 4.5.2. In versions 4.5.2 and up, this XmlResolver is set to null by default.
The following example shows how it is made safe:
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();
}
For .NET Framework version ≥4.5.2, this is safe by default.
对于.NET Framework版本≥4.5.2,默认情况下这是安全的**。
XmlDocument can become unsafe if you create your own nonnull XmlResolver with default or unsafe settings. If you need to enable DTD processing, instructions on how to do so safely are described in detail in the referenced MSDN article.
如果使用默认或不安全的设置创建自己的非null XmlResolver,XmlDocument可能会变得不安全。如果您需要启用DTD处理,如何在安全的情况下进行操作的详细说明可以在引用的MSDN文章中找到。
XmlNodeReader¶
System.Xml.XmlNodeReader objects are safe by default and will ignore DTDs even when constructed with an unsafe parser or wrapped in another unsafe parser.
默认情况下,System.Xml.XmlNodeReader对象是安全的,即使使用不安全的解析器或被另一个不安全的解析器包装,也会忽略DTD。
XmlReader¶
System.Xml.XmlReader objects are safe by default.
默认情况下,System.Xml.XmlReader对象是安全的。
They are set by default to have their ProhibitDtd property set to false in .NET Framework versions 4.0 and earlier, or their DtdProcessing property set to Prohibit in .NET versions 4.0 and later.
在.NET Framework 4.0及更早版本中,它们默认将ProhibitDtd属性设置为false;在.NET 4.0及以后的版本中,它们的DtdProcessing属性设置为Prohibit。
Additionally, in .NET versions 4.5.2 and later, the XmlReaderSettings belonging to the XmlReader has its XmlResolver set to null by default, which provides an additional layer of safety.
此外,在.NET 4.5.2及以后的版本中,XmlReader所属的XmlReaderSettings默认将XmlResolver设置为null,这提供了额外的安全层。
Therefore, XmlReader objects will only become unsafe in version 4.5.2 and up if both the DtdProcessing property is set to Parse and the XmlReaderSetting's XmlResolver is set to a nonnull XmlResolver with default or unsafe settings. If you need to enable DTD processing, instructions on how to do so safely are described in detail in the referenced MSDN article.
因此,XmlReader 对象只有在版本 4.5.2 及以上,且 DtdProcessing 属性设置为解析,以及 XmlReaderSetting 的 XmlResolver 设置为非空且具有默认或不安全设置的 XmlResolver 时才会变得不安全。如果您需要启用 DTD 处理,如何在安全的情况下进行操作的详细说明可以在 引用的 MSDN 文章 中找到。
XmlTextReader¶
System.Xml.XmlTextReader is unsafe by default in .NET Framework versions prior to 4.5.2. Here is how to make it safe in various .NET versions:
在 .NET Framework 版本低于 4.5.2 中,System.Xml.XmlTextReader 默认为 不安全。以下是在各种 .NET 版本中使其安全的方法:
Prior to .NET 4.0 / 在 .NET 4.0 之前¶
In .NET Framework versions prior to 4.0, DTD parsing behavior for XmlReader objects like XmlTextReader are controlled by the Boolean ProhibitDtd property found in the System.Xml.XmlReaderSettings and System.Xml.XmlTextReader classes.
在 .NET Framework 版本低于 4.0 中,XmlReader 对象(如 XmlTextReader)的 DTD 解析行为由 System.Xml.XmlReaderSettings 和 System.Xml.XmlTextReader 类中的布尔型 ProhibitDtd 属性控制。
Set these values to true to disable inline DTDs completely.
将这些值设置为 true 以完全禁用内联 DTD。
XmlTextReader reader = new XmlTextReader(stream);
// NEEDED because the default is FALSE!!
reader.ProhibitDtd = true;
.NET 4.0 - .NET 4.5.2¶
In .NET Framework version 4.0, DTD parsing behavior has been changed. The ProhibitDtd property has been deprecated in favor of the new DtdProcessing property.
在 .NET Framework 版本 4.0 中,DTD 解析行为已更改。ProhibitDtd 属性已被新的 DtdProcessing 属性所取代。
However, they didn't change the default settings so XmlTextReader is still vulnerable to XXE by default.
然而,他们没有更改默认设置,因此XmlTextReader默认仍然容易受到XXE攻击。
Setting DtdProcessing to Prohibit causes the runtime to throw an exception if a <!DOCTYPE> element is present in the XML.
将DtdProcessing设置为Prohibit会导致运行时在XML中存在<!DOCTYPE>元素时抛出异常。
To set this value yourself, it looks like this:
要自己设置此值,看起来是这样的:
XmlTextReader reader = new XmlTextReader(stream);
// NEEDED because the default is Parse!!
reader.DtdProcessing = DtdProcessing.Prohibit;
Alternatively, you can set the DtdProcessing property to Ignore, which will not throw an exception on encountering a <!DOCTYPE> element but will simply skip over it and not process it. Finally, you can set DtdProcessing to Parse if you do want to allow and process inline DTDs.
或者,您可以将DtdProcessing属性设置为Ignore,这样在遇到<!DOCTYPE>元素时不会抛出异常,而是简单地跳过它并不对它进行处理。最后,如果您希望允许并处理内联DTD,可以将DtdProcessing设置为Parse。
.NET 4.5.2 and later / .NET 4.5.2及以后版本¶
In .NET Framework versions 4.5.2 and up, XmlTextReader's internal XmlResolver is set to null by default, making the XmlTextReader ignore DTDs by default. The XmlTextReader can become unsafe if you create your own nonnull XmlResolver with default or unsafe settings.
在.NET Framework 4.5.2及以后的版本中,XmlTextReader的内部XmlResolver默认设置为null,使得XmlTextReader默认忽略DTD。如果您创建自己的非null XmlResolver并使用默认或不安全设置,XmlTextReader可能会变得不安全。
XPathNavigator¶
System.Xml.XPath.XPathNavigator is unsafe by default in .NET Framework versions prior to 4.5.2.
在.NET Framework版本4.5.2之前的版本中,System.Xml.XPath.XPathNavigator默认是不安全的。
This is due to the fact that it implements IXPathNavigable objects like XmlDocument, which are also unsafe by default in versions prior to 4.5.2.
这是由于它实现了像 XmlDocument 这样的 IXPathNavigable 对象,这些对象在 4.5.2 版本之前默认是不安全的。
You can make XPathNavigator safe by giving it a safe parser like XmlReader (which is safe by default) in the XPathDocument's constructor.
您可以通过在 XPathDocument 构造函数中提供一个安全的解析器(如默认安全的 XmlReader)来使 XPathNavigator 安全。
Here is an example:
以下是一个示例:
XmlReader reader = XmlReader.Create("example.xml");
XPathDocument doc = new XPathDocument(reader);
XPathNavigator nav = doc.CreateNavigator();
string xml = nav.InnerXml.ToString();
For .NET Framework version ≥4.5.2, XPathNavigator is safe by default.
对于 .NET Framework 版本 ≥4.5.2,XPathNavigator 默认是 安全的。
XslCompiledTransform¶
System.Xml.Xsl.XslCompiledTransform (an XML transformer) is safe by default as long as the parser it's given is safe.
只要提供的解析器是安全的,System.Xml.Xsl.XslCompiledTransform(一个 XML 转换器)默认是安全的。
It is safe by default because the default parser of the Transform() methods is an XmlReader, which is safe by default (per above).
它默认是安全的,因为 Transform() 方法的默认解析器是一个 XmlReader,而 XmlReader 默认是安全的(如上所述)。
The source code for this method is here.) (此方法的源代码在此。)
Some of the Transform() methods accept an XmlReader or IXPathNavigable (e.g., XmlDocument) as an input, and if you pass in an unsafe XML Parser then the Transform will also be unsafe.
一些 Transform() 方法接受 XmlReader 或 IXPathNavigable(例如 XmlDocument)作为输入,如果你传递了一个不安全的 XML 解析器,那么 Transform 也将是不安全的。
iOS¶
libxml2¶
iOS includes the C/C++ libxml2 library described above, so that guidance applies if you are using libxml2 directly.
iOS 包含上述的 C/C++ libxml2 库,因此如果你直接使用 libxml2,则该指南适用。
However, the version of libxml2 provided up through iOS6 is prior to version 2.9 of libxml2 (which protects against XXE by default).
然而,iOS6 及之前提供的 libxml2 版本早于 libxml2 的 2.9 版本(该版本默认保护 XXE)。
NSXMLDocument¶
iOS also provides an NSXMLDocument type, which is built on top of libxml2.
iOS 还提供了 NSXMLDocument 类型,它是基于 libxml2 构建的。
However, NSXMLDocument provides some additional protections against XXE that aren't available in libxml2 directly.
然而,NSXMLDocument 提供了一些针对 XXE 的额外保护,这些保护在直接使用 libxml2 时不可用。
Per the 'NSXMLDocument External Entity Restriction API' section of this page:
根据此 页面 的 'NSXMLDocument 外部实体限制 API' 部分:
- iOS4 and earlier: All external entities are loaded by default.
中文:iOS4 及之前版本:默认加载所有外部实体。 - iOS5 and later: Only entities that don't require network access are loaded. (which is safer)
中文:iOS5及以后版本:仅加载不需要网络访问的实体(这更安全)
However, to completely disable XXE in an NSXMLDocument in any version of iOS you simply specify NSXMLNodeLoadExternalEntitiesNever when creating the NSXMLDocument.
然而,要在iOS的任何版本中完全禁用NSXMLDocument中的XXE,只需在创建NSXMLDocument时指定NSXMLNodeLoadExternalEntitiesNever即可。
PHP¶
With libxml 2.9.0 or later, entity substitution is disabled by default. Do not enable LIBXML_NOENT, LIBXML_DTDLOAD, or LIBXML_DTDVALID for untrusted XML without explicitly blocking external resources; these options can require additional protection against external entity loading.
从libxml 2.9.0版本开始,默认禁用实体替换。在不信任的XML中,不要启用LIBXML_NOENT、LIBXML_DTDLOAD或LIBXML_DTDVALID选项,除非显式阻止外部资源;这些选项可能需要额外的保护措施以防止外部实体加载。
To reject external entity resolution, install a resolver callback that returns null before processing untrusted XML and keep it installed for that operation:
要拒绝外部实体解析,在处理不信任的XML之前,安装一个返回null的解析器回调函数,并在该操作期间保持安装状态:
libxml_set_external_entity_loader(function () {
return null;
});
Passing null directly to libxml_set_external_entity_loader() is not equivalent to returning null from the callback and does not block external entity loading, as the PHP security advisory's mitigation demonstrates.
直接将null传递给libxml_set_external_entity_loader()与从回调函数返回null不等效,并且不会阻止外部实体加载,正如PHP安全公告的缓解措施所展示的。
A description of how to abuse this in PHP is presented in a good SensePost article describing a cool PHP based XXE vulnerability that was fixed in Facebook.
如何在PHP中滥用此功能,在SensePost文章中有很好的描述SensePost文章,描述了一个酷炫的基于PHP的XXE漏洞,该漏洞已在Facebook中得到修复。
Python¶
Follow Python's current XML security guidance. The built-in parsers rely on Expat, which may be bundled with Python or supplied by the operating system. Check pyexpat.EXPAT_VERSION in the deployed interpreter and keep both Python and Expat updated. Expat versions below 2.7.2 may be affected by entity-expansion, large-token, or dynamic-memory denial-of-service vulnerabilities; a Python version alone does not establish the linked Expat version.
遵循Python当前的XML安全指南。内置解析器依赖于Expat,它可能包含在Python中或由操作系统提供。检查已部署解释器的pyexpat.EXPAT_VERSION,并保持Python和Expat的更新。低于2.7.2版本的Expat可能受到实体扩展、大令牌或动态内存拒绝服务漏洞的影响;仅Python版本并不能确定链接的Expat版本。
Expat itself does not access files or the network by default. Higher-level APIs and custom handlers still need an external-resource policy. Independently bound input size and decompressed data: the standard-library xmlrpc module is vulnerable to decompression bombs.
Expat本身默认不访问文件或网络。高级API和自定义处理程序仍然需要一个外部资源策略。独立绑定的输入大小和解压缩数据:标准库的xmlrpc模块容易受到解压缩炸弹的攻击。
For untrusted XML, use the defusedxml parsing interfaces in place of the corresponding standard-library parsing functions. Keep entity and external-resource rejection enabled, and set forbid_dtd=True on APIs that offer it when DTDs are unnecessary. These interfaces reject prohibited constructs; they do not sanitize XML or replace application resource limits.
对于不受信任的 XML,请使用 defusedxml 解析接口 替代相应的标准库解析函数。保持实体和外部资源拒绝功能开启,并在 API 提供时将 forbid_dtd=True 设置在 DTD 无需使用的情况下。这些接口拒绝禁止的结构;它们不清理 XML 或替换应用程序资源限制。
Semgrep Rules / Semgrep 规则¶
Semgrep is a command-line tool for offline static analysis. Use pre-built or custom rules to enforce code and security standards in your codebase.
Java¶
Below are the rules for different XML parsers in Java
以下是 Java 中不同 XML 解析器的规则
DocumentBuilderFactory¶
Identifying XXE vulnerability in the javax.xml.parsers.DocumentBuilderFactory library.
The official registry rule is documentbuilderfactory-disallow-doctype-decl-missing.
在 javax.xml.parsers.DocumentBuilderFactory 库中识别 XXE 漏洞。官方注册规则是 documentbuilderfactory-disallow-doctype-decl-missing。
SAXParserFactory¶
Identifying XXE vulnerability in the javax.xml.parsers.SAXParserFactory library.
The official registry rule is saxparserfactory-disallow-doctype-decl-missing.
在 javax.xml.parsers.SAXParserFactory 库中识别 XXE 漏洞。官方注册规则是 saxparserfactory-disallow-doctype-decl-missing。
XMLInputFactory¶
Identifying XXE vulnerability in the javax.xml.stream.XMLInputFactory library.
The official registry rule is xmlinputfactory-possible-xxe.
在 javax.xml.stream.XMLInputFactory 库中识别 XXE 漏洞。官方注册规则是 xmlinputfactory-possible-xxe。
References / 参考¶
- Oracle Java 25: JAXP Security Guide) (Oracle Java 25: JAXP 安全指南)
- Python: XML Security) (Python: XML 安全)
- Morgan and Al Ibrahim: XML Schema, DTD, and Entity Attacks) (Morgan 和 Al Ibrahim: XML 模式、DTD 和实体攻击)