System.Xml Security Considerations
The following sections discuss the types of security issues that can arise when working with System.Xml components what you can do to mitigate these threats.
The System.Xml components rely on the Microsoft .NET Framework security system. This topic only addresses security issues that are specifically handled by the XML classes. For more information, see Security in the .NET Framework.
XmlReader and XmlReaderSettings Classes
Document Object Model
The XmlResolver class is used to resolve resources. It is used to load XML documents, and to resolve external resources such as entities, DTDs or schemas, and import or include directives. The .NET Framework includes two implementations of the XmlResolver class.
The XmlUrlResolver class is the default resolver for all classes in the System.Xml namespace. It supports the file:// and http:// protocols and requests from the WebRequest class. In many cases, if you do not specify an XmlResolver object that your application should use, an XmlUrlResolver object with no user credentials is used to access XML resources.
The XmlSecureResolver class helps to secure another XmlResolver object by wrapping the XmlResolver object and restricting the resources that the underlying XmlResolver has access to. For example, the XmlSecureResolver class can prohibit access to particular Internet sites or zones.
You should consider the following items when working with the XmlResolver class.
XmlResolver objects can contain sensitive information such as user credentials that can be used to access and retrieve data. You should be careful when caching XmlResolver objects and should not pass the XmlResolver object to an untrusted component because the untrusted component could use the XmlResolver and its user credentials to access data.
If you are designing a class property that uses the XmlResolver class, the property should be defined as a write-only property. The property can be used to specify the XmlResolver to use, but it cannot be used to return an XmlResolver object. This allows an untrusted component use the class, but does not allow it to retrieve and directly use the XmlResolver object.
If your application accepts XmlResolver objects from untrusted code, you cannot assume that the URI passed into the GetEntity method is the same as that returned by the ResolveUri method. Classes derived from the XmlResolver class can override the GetEntity method and return data that is different than what was contained in the original URI.
Your application can mitigate memory denial of service threats to the GetEntity method by implementing a wrapping implemented IStream that limits the number of bytes read. This helps to guard against situations where malicious code attempts to pass an infinite stream of bytes to the GetEntity method.
XmlReader and XmlReaderSettings Classes
Virtually all System.Xml components are built on top of the concept of parsing XML. For example, the XmlDocument class uses the XmlReader class to parse a document and build an in-memory representation of the XML document.
Limiting Document and Entity Expansion Size
Memory usage of an application that uses XmlReader may have a correlation to the size of the parsed XML document. One form of denial of service attack is when excessively large XML documents are submitted to be parsed.
When using XmlReader, you can limit the size of the document that can be parsed by setting the MaxCharactersInDocument property. You can limit the number of characters that result from expanding entities by setting the MaxCharactersFromEntities property. See the appropriate reference topics for examples of setting these properties.
DTD processing may lead to a denial of service condition. For example, the DTD may contain nested entities or complex content models that can take an inordinate amount of time to process.
The ProcessInlineSchema and ProcessSchemaLocation validation flags of an XmlReaderSettings object are not set by default. This helps to protect the XmlReader against schema-based attacks when it is processing XML data from an untrusted source. When these flags are set, the XmlResolver of the XmlReaderSettings object is used to resolve schema locations encountered in the instance document in the XmlReader. If the XmlResolver property is set to null, schema locations are not resolved even if the ProcessInlineSchema and ProcessSchemaLocation validation flags are set.
Schemas added during validation add new types and can change the validation outcome of the document being validated. As a result, external schemas should only be resolved from trusted sources.
We recommend disabling the ProcessIdentityConstraints flag (enabled by default) when validating, untrusted, large XML documents in high availability scenarios against a schema with identity constraints over a large part of the document.
XML data can include references to external resources such as a schema file. By default external resources are resolved using an XmlUrlResolver object with no user credentials. This means that, by default, you can access any locations that do not require credentials. You can secure this further by doing one of the following:
Sharing XmlReaderSettings Objects
XmlReaderSettings objects can contain sensitive information such as user credentials. An untrusted component could use the XmlReaderSettings object and its user credentials to create XmlReader objects to read data. You should be careful when caching XmlReaderSettings objects, or when passing the XmlReaderSettings object from one component to another.
- Do not accept supporting components, such as NameTable, XmlNamespaceManager, and XmlResolver objects, from an untrusted source.
XML data can contain a large number of attributes, namespace declarations, nested elements and so on that require a substantial amount of time to process.
You can create a custom IStream implementation that limits the size of input used and supply this to the XmlReader class.
Use the ReadValueChunk method to handle large streams of data. This method reads a small number of characters at a time instead of allocating a single string for the whole value.
By default general entities are not expanded. General entities are expanded when you call the ResolveEntity method.
XML data can include references to external resources such as DTD references. By default external resources are resolved using an XmlUrlResolver object with no user credentials.
You can secure this further by doing one of the following:
The XslCompiledTransform class is an XSLT processor XSLT processor that supports the XSLT 1.0 syntax. It allows you to transforms XML data using an XSLT style sheet.
Style sheets can include references to external resources such as xsl:import or xsl:include elements or the document() function.
The XslCompiledTransform class supports the xsl:import or xsl:include elements by default. The XslCompiledTransform class disables support for the document() function by default. The XsltSettings class is used to enable the document() function.
You can control how external resources are accessed by doing one of the following:
Restrict the resources that the XSLT process can access by using an XmlSecureResolver object.
Do not allow the XSLT process open any external resources by passing in null to the XmlResolver argument.
The XslCompiledTransform class does not support script blocks by default. Script blocks are enabled using the XsltSettings class. XSLT scripting should be enabled only if you require script support and you are working in a fully trusted environment.
Extension objects add programming capabilities to XSLT transformations. This feature is enabled by default. If extension objects are passed to the Transform method, they are used in the XSLT transformation.
Document Object Model
Because the Document Object Model (DOM) caches all data in memory, DOM operations such as querying, editing, moving sub-trees between documents, and saving DOM objects are not recommended if you are working with untrusted data and are concerned about denial of service attacks. Another option is to set a limit for how much data to read into the DOM. One way to do this is to create a custom stream implementation that limits the size of input used and use this to load the DOM object.
XmlDocument objects can contain sensitive information such as user credentials in the embedded XmlResolver object. If the XmlDocument.XmlResolver property is set to an XmlResolver object with user credentials, you should not cache the XmlDocument object or pass it to an untrusted component. An untrusted component could use the DOM object, and the embedded XmlResolver user credentials, to access and load data.