Wednesday, May 11, 2005

Security considerations for XML messaging

XML technologies are an interesting beast. They are used for such a wide variety of purposes that many of the specifications have features seriously impact the security of various potential applications, but which are completely ignored/missed, because no-one would ever legitimately use those features in that context. Most serious web-service frameworks, protect you from the obvious issues I discuss below, but when building a service from scratch, keep this in mind. Even when using a framework, remember that someday someone might try and maliciously construct messages, designed to negatively impact your service. The internet is a wonderful thing, not just for you, but for the person who decides to try and hack you.

One obvious example of one of XML's features with large security implications are DTDs. There are a number of aspects of DTD handling which have serious security implications for middle-tier and back-end systems consuming untrusted XML. For example, external entities. Most XML parsers, by default, support DTDs and will resolve external entities. That means that the obvious implementation of a web service (non-SOAP) would be vulnerable to a large class of attacks based on sending data that looked vaguely like this:

<DOCTYPE foo [
<!ENTITY e SYSTEM "/etc/passwd">]>

You might argue that there is no inherent risk since your service probably doesn't send that data back to the client, but the mere fact that it tricked your
web service into loading data to which the client itself did not have access, is a security vulnerability.

There are multiple lessons here. For people implementing middle-tier or back-end systems, make sure that you actively disable all the 'features' you don't need. For XML, that may mean disabling DTDs, Schema support, inline Schema support, and XInclude; at least that is the list of options that most immediately springs to mind.

In MSXML, using DOMDocument, that would look something like this:

doc.async = false;
doc.validateOnParse = false;

doc.resolveExternals = false;

doc.setProperty("MaxXMLSize", ...);
doc.setProperty("ProhibitDTD", true);

In my web scripting, I usually factor all that into a helper function that also CoCreate-s the DOMDocument object, so that the rest of the code needn't worry about it.

In System.Xml, it is easier. Validation is not enabled by default, and async parsing just isn't supported, so you need only disable DTD support (XmlTextReader.ProhibitDTD) and if you are paranoid, block external resolution (XmlTextReader.XmlResolver = null).

The more versatile the tool, the better to unintentionally shoot oneself in the foot with it.


Post a Comment

<< Home