Code Reference A collection of code for my reference (and perhaps other people too)

4Dec/090

Preventing XML Bombs

The Nobember (2009) issue of Msdn Magazine has a great article on XML Bombs and XML External Entity Attacks (DoS attatcks).

This was extremely useful to us as we are in the process of publishing a webservice that will be extensively used. Our current service is attacked regularly. Luckily, the attacks have been pretty basic and our security protects us. We were vulnerable to these types of attacks, but no longer are.

Example of an XML Bomb
XML Bombs use the XML document type definition (DTD) to create a piece of XML that, when parsed, will inflate to a huge size and consume all the resources on your machine.

Here is an example of such an attack from the article:

<?xml version="1.0"?>
<!DOCTYPE lolz [
   <!ENTITY lol "lol">
   <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
   <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
   <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
   <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
   <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
   <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
   <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
   <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

The above code loops internally to create an object of about 3GB of memory. Impressive.
The 2nd entity consists of 10 of the 1st entity.
The 3rd entity consists of 10 of the 2nd entity (10 x 10 of the first).
The 4th entity consists of 10 of the 3rd entity (10 x 10 x 10 first).
And so on. The final XML is huge.

Preventing XML Bombs can be easily done by disabing inline DTDs.

Doing so is different in .Net 3.5 vs .Net 4.0

In .Net 3.5 you can use the ProhibitDtd boolean in the XmlTextReader or XmlReaderSettings.

// default is false
XmlTextReader reader = new XmlTextReader(myStream);
reader.ProhibitDtd = true; 

or 

// default is true
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlTextReader reader = new XmlTextReader(myStream, settings);

In .Net 4.0 you can use the DtdProcessing property. It can be set to Prohibit or Ingore. The ProhibitDtd property has been removed in 4.0.

// Prohibit will throw an exception if there is a <!DOCTYPE>
XmlREaderSettings settings = new XmlReaderSettngs();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlTextReader reader = new XmlTextReader(myStream, settings);

or

// Ingore will NOT throw an exception if there is a <!DOCTYPE>. It will ignore all DTDs.
XmlREaderSettings settings = new XmlReaderSettngs();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlTextReader reader = new XmlTextReader(myStream, settings);

If you would like to parse the DTDs, you should limit the size of the expanded DTDs.
This is easily done using the settings.

// default is true
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1024; // 1 KB
XmlTextReader reader = new XmlTextReader(myStream, settings);
Tagged as: , Leave a comment
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.