Protecting Against XML Bombs

XML Bombs are an easy way for an attacker to perform a denial-of-service attack against your server, if it accepts XML uploads.

Risks

Prevalence Rare
Exploitability Easy
Impact Devastating

A malicious XML file could take your server offline, causing the loss of critical functions and the loss of revenue. Protecting yourself is a matter of making sure your XML parser is properly configured.

Protection

Disable Parsing of Inline DTDs

Inline DTDs are a rarely used feature. However, XML bombs remain a common vulnerability, because many XML parsing libraries do not disable this feature by default. If you use XML parsing, make sure your parser configuration disables this feature. See the code samples below, or consult your API documentation to see how.

Consider Making XML Parsing Asynchronous

Parsing large XML files can take a lot of time and memory. If your architecture doesn’t do so already, consider making the parsing of large XML files asynchronous. As XML files are uploaded, move them over to a queue, and have a separate process pop them off the queue and handle the parsing duties.

This approach will improve the scalability and stability of your system, because onerous parsing jobs won’t take your web server offline. (AJAX requests are the exception here – they need to be handled by the web server, since they are part of the HTTP request-response cycle.)

Throttle Uploads Per Client

If you are accepting XML uploads from identified accounts, it is a good idea to restrict the number of simultaneous parsing jobs per account. This will protect you from accidental denial-of-service attacks, should a downstream system start to overload your system.

Code Samples

The following code samples indicate how to disable inline DTDs in the major XML-parsing libraries.

Use the defusedxml libraries for XML parsing – they have been deliberately hardened against all the vulnerabilities described here.

Nokogiri

# Open the XML file, perform config by pass a block.
doc = Nokogiri::XML(File.open("data.xml")) do |config|
  config.strict.noent
end


DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);

.NET 3.5 and Before

// Disable directly on the reader...
XmlTextReader reader = new XmlTextReader(stream);
reader.ProhibitDtd = true;

// ...or on the settings object.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);

.NET 4.0 and After

// Will throw an error if a !DOCTYPE element occurs.
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(stream, settings);

Is your website vulnerable to XML Bombs?

Check today. Scan your website for XML Bombs and other vulnerabilities with the