Skip to main content

XML injection (XXE) - Unmarshaller

Need

Secure configuration of XML unmarshaller

Context

  • Usage of PHP for server-side web development
  • Usage of Illuminate\Http\Request for handling HTTP requests in Laravel

Description

Non compliant code

<?php

use Illuminate\\Http\\Request;

class XmlController extends Controller
{
public function parseXml(Request $request)
{
$xmlString = $request->input('xmlData');
$xml = simplexml_load_string($xmlString);

// Process the XML data...
}
}

The above code is an example of a Laravel controller method that is vulnerable to XML External Entity (XXE) injection.

This method, parseXml(), takes a request object as a parameter and retrieves XML data from the request's input. It then uses PHP's simplexml_load_string() function to parse the XML data into an object that can be manipulated by PHP.

The vulnerability lies in the fact that simplexml_load_string() does not disable the loading of external entities by default. This means that if the XML data contains a reference to an external entity, PHP will attempt to load it.

An attacker could exploit this by sending XML data that includes a reference to a file on the server's file system. If the server processes this XML data, it could potentially expose sensitive information, such as passwords or configuration files.

Here's an example of how an attacker might exploit this vulnerability:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<foo>&xxe;</foo>

In this example, the <!ENTITY xxe SYSTEM "file:///etc/passwd" > line defines an entity that references the /etc/passwd file, which typically contains user account information on a Unix-like system. The <foo>&xxe;</foo> line then uses this entity, causing the server to insert the contents of the /etc/passwd file into the XML data.

Steps

  • Disable external entity loading in the XML parser to prevent XML External Entity (XXE) attacks.
  • Use the libxml_disable_entity_loader function before parsing the XML data.
  • Always validate the XML data before parsing it. This can be done using a schema or DTD to ensure the XML data is in the expected format.
  • Avoid showing detailed error messages to the user, as they can reveal information about the system that could be exploited by an attacker.

Compliant code

<?php

use Illuminate\\Http\\Request;

class XmlController extends Controller
{
public function parseXml(Request $request)
{
$xmlString = $request->input('xmlData');

// Disable external entity loading to prevent XXE attacks
libxml_disable_entity_loader(true);

// Load the XML string
$xml = simplexml_load_string($xmlString, 'SimpleXMLElement', LIBXML_NOENT);

// Process the XML data...
}
}

The updated code now includes a call to the libxml_disable_entity_loader(true) function before parsing the XML data. This function disables the ability for XML to load external entities, which is a common method used in XML External Entity (XXE) attacks. By disabling this feature, we can prevent potential XXE attacks.

The simplexml_load_string function is also updated with two additional parameters: 'SimpleXMLElement' and LIBXML_NOENT. The 'SimpleXMLElement' parameter specifies the class that new objects will be created from. The LIBXML_NOENT parameter substitutes entities, which can help prevent XXE attacks by ensuring that no external entities are loaded.

Please note that this code does not include XML data validation. It's highly recommended to validate the XML data before parsing it. This can be done using a schema or DTD to ensure the XML data is in the expected format.

Also, avoid showing detailed error messages to the user, as they can reveal information about the system that could be exploited by an attacker. Instead, log the errors internally and show a generic error message to the user.

References