XXE attacks 😈 PDF, Excel, SVG, ebooks β€” all use XML. They can be vulnerable.

Β· by

Contents

XML is probably the most commonly used markup language. It’s organized around tags <example>foo</example> and allows pretty complicated structures.

One interesting property of XML is that you can reference external entities, e.g. you can include another file. That is where the name XXE comes from: XML external entities. Let’s start!

Why you should care

  • XXE vulnerabilities can allow attackers to steal your data, scan your internal network, and even allow remote code execution (RCE)
  • XXE attacks were number 4 in the OWASP Top 10 (2017)
  • The Twitter Tag #XXE is pretty active. So people are still interested in it, although the vulnerability was already recognized in 2002 (source)
  • 2012: An XXE vulnerability was discovered in Inkscape (source)
  • 2014: Google was vulnerable to XXE and paid a bug bounty of $10,000 (source)
  • 2014: Adobe Reader had an XXE vulnerability (source)
  • 2015: Mohamed Ramadan discovered an XXE vulnerability in Facebook's resume upload (source)
  • 2020: IBM QRadar had an XXE vulnerability (source)

We don’t use XML!

Here are some indicators that you might need to care:

  • You’re using SOAP
  • You’re using SAML
  • You’re reading office files, such as Word (docx) or Excel files (xlsx; example, example). PowerPoint (pptx) contains XML as well. All of them are essentially ZIP archives with lots of XML files inside. I don’t think that Word / Excel / PowerPoint are vulnerable, but maybe the smaller libraries around those files that are used to programmatically create or read them.
  • You’re reading XMP metadata from images such as JPG or GIF (presentation, slides), metadata from audio and video files as well.
  • You’re reading PDF files
  • SVGs are XML as well.

The oxml_xxe tool makes it pretty easy to generate such a malicious file.

Types of XXEs

  • In-band: The output is shown to the attacker
  • Out of band (OOB): The attacker is blind

In-band XXE

from lxml import etree

xml = """<root>Hello World!</root>"""
parser = etree.XMLParser()
doc = etree.fromstring(xml.encode(), parser)
parsed_xml = etree.tostring(doc).decode("utf8")
print(parsed_xml)

Looks harmless, doesn’t it? It simply prints <root>Hello World!</root>.

But if you change the xml string, then you can read the list of users in /etc/passwd:

from lxml import etree

xml = """
<!DOCTYPE XML [
<!ENTITY ee SYSTEM "file:///etc/passwd" >
]>
<root>&ee;</root>
"""
parser = etree.XMLParser()
doc = etree.fromstring(xml.encode(), parser)
parsed_xml = etree.tostring(doc).decode("utf8")
print(parsed_xml)

If this were part of a server, then an attacker could read arbitrary files on that server.

Out-of-Band XXE

Most of the time, the attacker cannot see the result of the parsed XML file directly. Hence, in-band XXE is not possible. And maybe errors are also captured, so an error-based XXE does not work either.

However, the attacker might be able to force the server to make HTTP calls. This is called server-side request forgery (SSRF). Then the attacker sets up a listener, forces the server to make a request, and thus confirms that XXE is possible. The attack looks similar to the lines above and is pretty well explained here:

Mitigations

The simplest mitigation is to limit the capabilities of XML to a safe subset. This means that you need to configure the XML parser you’re using.

Python has 5 XML parsers: sax, etree, minidom, pulldom, xmlrpc. According to the documentation, they are safe to use. However, lxml is widespread. It mentions that you should configure the parser to not load external DTDs (source). The defusedxml package offers a way to access XML parsers with a secure default configuration.

See also

I would like to point you to this YouTube video by PwnFunction. It summarizes the topic very well.

If you’re interested in an overview of different XML parsers, try SoK: XML Parser Vulnerabilities (2016) by Christopher Späth, Christian Mainka, Vladislav Mladenov, and Jörg Schwenk.

More in this series

In this series about application security (AppSec), we already explained some of the techniques of the attackers 😈 and also techniques of the defenders πŸ˜‡:

The following articles are about to come:

  • Part 18: Secure Messaging πŸ˜‡
  • Part 19: Cryptojacking 😈
  • Part 20: Backups πŸ˜‡
  • Part 21: Cryptotrojans 😈
  • Part 22: Single-Sign-On πŸ˜‡
  • Part 23: Clipboard Hijacking 😈
  • Part 24: Certificates πŸ˜‡
  • Part 25: Race Condition Attacks in Blockchains 😈
  • Part 26: Mobile Device Management (MDM) πŸ˜‡
  • Part 27: Server-Side Request Forgery (SSRF) 😈
  • Part 28: Network Separation πŸ˜‡
  • Part 29: Social Engineering (including Phishing) 😈
  • Part 30: Virtual Private Networks (VPNs) πŸ˜‡
  • Part 31: CSRF 😈

Let me know if you are interested in more articles around AppSec / InfoSec!