Protecting Against XML External Entity Attacks

Unsecured XML parsers can permit an attacker to probe your file system for sensitive information. If your site accepts XML in any fashion, you need to ensure your parser is correctly configured.

Risks

Prevalence Rare
Exploitability Difficult
Impact Devastating

XML External Entity attacks allow a malicious user to read arbitrary files on your server. Getting access to the server’s file system is often the first step an attacker will take when compromising your system. Unless you deploy a intrusion detection system, you will often not know it is occurring until it’s too late.

Even big companies like Facebook have suffered from this vulnerability in the past.

Protection

Disable Parsing of Inline DTDs

Inline DTDs are a feature that is rarely used. However, XML external attacks remain a risk because many XML parsing libraries do not disable this feature by default. Make sure your XML parser configuration disables this feature. See the code samples below, or consult your API documentation. Making this simple configuration change will protect you against XML External Entity attacks, and XML Bombs.

Limit the Permissions of Your Web Server Process

Run your server processes with only the permissions they require to function – follow the principle of least privilege. This means restricting which directories in the file-system can be accessed. Consider running in a chroot jail if you are running on Unix.

This “defense in depth” approach means that even if an attacker manages to compromise your web server, the damage they can do is limited.

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

You can disable expanding of external entities in Nokogiri in the following manner:


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

Note that Nokogiri forbids network access when expanding external entities by default, since it uses the nonet configuration option.


DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
String FEATURE = "http://apache.org/xml/features/disallow-doctype-decl";
dbf.setFeature(FEATURE, true);

.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);

Further Reading