XML external entity injection (XXE)

Injected untrusted data into an XML parser

Select your ecosystem

XXE: the basics

What is XXE?

XML external entity injection (XXE) is an attack where untrusted data is provided to a misconfigured XML parser.

XML structures data by using tags, and provides a rigid schema mechanism that describes the nesting, presence, and type of tags. For example, XML is used in communicating data between client and server, or to locally serialize and store data.

The XML standard has a concept called an “entity”, which represents a unit of data and there are many different types of entities in the XML specification. There is a type of custom entity called an “XML External Entity'' denoted by the use of the SYSTEM keyword. The entity specifies a URL where the entity is defined, using either HTTP or file protocols. External entities can be used to retrieve both remote and local files.

If an XML parser is configured to allow external entities, attackers can take advantage of this to access internal resources, including the server’s file system and other connected systems.

About this lesson

In this lesson, we will cover how to conduct an XXE injection attack, why the attack works, and how to prevent it from happening. We’ll explore the website of a fictional essential oils company, “Oliver’s Oils”, exploit the XXE injection vulnerability, and learn about what happened under the hood by diving into the code. Last but not least, we will fix the application so that it’s no longer vulnerable.

FUN FACT

Billion laughs attack

There is an alternative denial of service (DOS) attack vector called the “billion laughs” attack, also referred to as an XML bomb, where an attacker can consume excessive resources by producing a considerable block of XML. The XML entity injection contains ten entities, the first one simply containing the string “lol”. All others are defined recursively as being ten of the previous entity. When these entities are parsed and expanded, there ends up being a billion “lols”, an XML document with a few hundred KB ends up taking almost 3GB of memory when parsed!

XXE in action

The OWASP Top 10 (2021) is the leading standard for awareness of the most critical web application security issues. Number 5 on the list is security misconfigurations, which now include XXE. Let's walk through an example of how we might discover and initiate an XXE attack.

Testing for XXE

  • STEP 1
  • STEP 2
  • STEP 3
  • STEP 4
  • STEP 5

Setting the stage

Let's see if we can execute a successful XXE attack. We'll need a browser extension and an external entity. Let's start the attack!

intro-screen

XXE under the hood

What happened?

In the example above, the “Oliver’s Oils” web application trusted the XML input we provided when we intercepted and edited the POST request. By injecting our custom external entity, the XML parser processed the entity and retrieved the contents of the /etc/passwd file, and then displayed the contents of the file along with the user’s favorites. This was possible because the XML parser that the web application uses has not disabled the use of external entities.

It’s worth noting that we aren’t just limited to local system files. Sometimes getting the response reflected in the web app, as we did in the above example, isn’t possible due to how the application works. In those cases, to exfiltrate the data, attackers can insert a remote location in the SYSTEM entity.

The vulnerable piece of code in our JavaScript app looks like the below:

The web application uses the libxml library as its parser library, as NodeJS doesn’t provide a native XML parser. The issue in this code is calling the XML parser with the noent:true option which allows for external entities.

Scan your code & stay secure with Snyk - for FREE!

Did you know you can use Snyk for free to verify that your code
doesn't include this or other vulnerabilities?

Scan your code

XXE mitigation

The safest way to mitigate XXE attacks in most frameworks is by disabling document type definitions completely. This will remove the ability to create custom entities. If this isn’t an option for your application, you’ll need to disable external entities and external document type declarations, depending on the parser in use.

In our situation, the parser libxmljs actually disables external entities by default! The noent:true option included when parsing the XML actually enabled it. So all we need to do is remove it!

Keep learning

  • You can also have a look at this great video explanation on YouTube
  • Read about High-severity XML External Entities (XXE) vulnerabilities found in the Nokogiri library in our blog
  • Are you curious how to configure Java to prevent XXE vulnerabilities? We have a great guide!
  • And of course don’t forget to check out the XXE Cheat Sheet from OWASP

Congratulations

You have taken your first step into learning what XXE is, how it works, what the impacts are, and how to protect your own applications. We hope that you will apply this knowledge to make your applications safer. We'd really appreciate it if you could take a minute to rate how valuable this lesson was for you and provide feedback to help us improve! Also, make sure to check out our lessons on other common vulnerabilities.