Wat is XXE (XML eXternal Entity)?
Veel moderne webapplicaties gebruiken nog steeds XML voor het transporteren en opslaan van gegevens. In 1996 creëerde het World Wide Web Consortium (W3C) deze standaard en tot op de dag van vandaag wordt deze gebruikt voor een grote verscheidenheid aan implementaties. XML heeft veel functies waar ontwikkelaars niet altijd bekend mee zijn, wat hackers een mogelijkheid tot misbruik biedt.
Onveilige implementaties van sommige XML-functies kunnen kwetsbaarheden introduceren, een daarvan is XML External Entity injection (XXE). XXE betekent dat de XML-functionaliteit van de toepassing kan worden gebruikt om externe bronnen op te halen via een verwijzing in de XML. Kwetsbare software die de XML parseert, interpreteert de verwijzing, waardoor XXE-aanvallen mogelijk zijn. Deze kwetsbaarheid kan soms worden gebruikt om bestanden van de server te lezen of zelfs om er commando’s op uit te voeren.
De XXE-kwetsbaarheid is een van de meest kritieke beveiligingsproblemen volgens de OWASP Top 10. Het is gecategoriseerd onder “A05:2021 – Misconfiguratie van de beveiliging” en is de 5e meest kritieke kwetsbaarheid in 2021.
XML-basis
XML staat ook bekend als Extensible Markup Language en is net als HTML gebaseerd op Standard Generalized Markup Language (SGML). Het XML-formaat heeft dus veel gemeen met het HTML-formaat. Het heeft ook declaraties, elementen en attributen, zoals weergegeven in de onderstaande afbeelding
Een XML-bestand begint met een XML-declaratie. Hiermee wordt aangegeven welke XML-versie wordt gebruikt. In de meeste gevallen is dit ingesteld op <?xml version=”1.0″?>.
Daarna vertelt de Document Type Declaration (DTD) de software hoe het bestand is opgebouwd. Dit wordt gedeclareerd in het element <!DOCTYPE …>. De auteur kan een definitie, of kan verwijzen naar een extern of lokaal definitiebestand. Deze definitie kan worden opgeslagen in een .dtd bestand of kan worden gedefinieerd in de Documenttype-declaratie met behulp van vierkante haakjes[ … ]. Het is ook heel gewoon om te verwijzen naar een externe DTD op het internet.
De DTD wordt gevolgd door de gegevens die zijn gestructureerd in elementen en attributen, waarbij (externe) entiteiten kunnen worden gebruikt.
Entiteiten in XML
Entiteiten kunnen worden vergeleken met een variabele in een programmeertaal. In het volgende voorbeeld bevat de entiteit msg de waarde “Hello World”. De waarde wordt opgeslagen in het <bericht> element. Een verwijzing naar deze entiteit wordt geschreven als &msg;.
<DOCTYPE xml [ <!ENTITY msg “Hello World”>]>
<xml>
<bericht>&msg;</bericht>
</xml>
Dit is een voorbeeld van een interne entiteit. Er zijn ook externe entiteiten en deze worden gebruikt in XXE aanvallen. Een externe entiteit kan worden gebruikt zoals in het onderstaande voorbeeld. In dit voorbeeld verwijst de entiteit ext naar een externe bron: https://example.com/. De software die de XML parseert, haalt de externe bron op wanneer het XML-bestand wordt geïnterpreteerd. Let ook op het sleutelwoord SYSTEM, dat aangeeft dat het een externe entiteit is.
<DOCTYPE xml [ <!ENTITY ext SYSTEM “http://example.com/” > ]>
<xml>
<site>&ext;</site>
</xml>
Naast het opvragen van gegevens uit externe bronnen, is het ook mogelijk om lokale bestanden (op de server) op te nemen met behulp van een externe entiteit.
XXE aanval
Een XXE-aanval is mogelijk wanneer XML-functionaliteiten worden gebruikt die gevaarlijke functies ondersteunen, zoals externe entiteiten. Om deze kwetsbaarheid te demonstreren, hebben we het xxelab van Joshua Barone gebruikt. Deze labomgeving is opzettelijk kwetsbaar voor XXE aanvallen voor testdoeleinden. Het bevat een kwetsbare applicatie met een registratieformulier dat XML gebruikt. De volgende schermafbeelding laat zien hoe de formuliergegevens zijn gestructureerd en hoe het element<email> terugkomt in het antwoord.
Om te controleren of dit formulier XML-entiteiten ondersteunt, gebruik je een interne entiteit, zoals dit: <!DOCTYPE foo [ <!ENTITY xxe “Dit is een interne entiteit” >]>
Omdat de waarde van <email> wordt weergegeven in het antwoord, kunnen we dit gebruiken om deze kwetsbaarheid uit te buiten. In het volgende voorbeeld wordt de entiteit XXE gebruikt om de waarde “Dit is een interne entiteit” weer te geven in het antwoord.
Om deze kwetsbaarheid uit te buiten om lokale bestanden te lezen, moet een externe entiteit worden gebruikt, zoals in het volgende voorbeeld:
<DOCTYPE foo [ < ENTITY xxe SYSTEM “file://etc/passwd” >]>
Deze externe entiteit verwijst naar het lokale bestand /etc/passwd op het bestandssysteem van de server waarop de applicatie staat. Omdat de waarde van <email> wordt weergegeven in het antwoord, kunnen we dit gebruiken om de inhoud van het lokale bestand /etc/passwd weer te geven. De schermafbeelding hieronder laat zien hoe de externe entiteit xxe kan worden gebruikt om het lokale bestand/etc/passwd te lezen:
Wat kun je nog meer doen met XXE?
Een XXE-aanval kan worden gebruikt voor meerdere exploitatieveectoren. Een XXE aanval kan worden gebruikt als een DoS aanval (bekend als de Billion Laughs aanval). Deze aanval maakt veel kopieën van een entiteit, waardoor de applicatie grote hoeveelheden servergeheugen moet gebruiken om de XML te verwerken.
In sommige gevallen kan een XXE kwetsbaarheid gebruikt worden om poorten te scannen. Dit kan worden bereikt door verwijzingen naar het interne netwerk. In sommige situaties kan de respons of responstijd een indicatie geven of de poort (waarnaar de URL in de externe entiteit verwijst) open of gesloten is.
En in het ergste geval kan een XXE-kwetsbaarheid ook worden gebruikt om commando’s direct op het lokale systeem uit te voeren.
XXE-kwetsbaarheden verhelpen
De meeste XXE kwetsbaarheden ontstaan wanneer een applicatie gevaarlijke functionaliteiten zoals externe XML entiteiten ondersteunt. De meest effectieve manier om deze kwetsbaarheden te beperken is dus het uitschakelen van deze functionaliteiten of het beperken van de toepassing door middel van filtering. Er zijn veel platformen en bibliotheken die XML ondersteunen, maar hier zijn enkele oplossingen voor enkele veelgebruikte:
⦁ Java – javax.xml.parsers.DocumentBuilderFactory
– factory.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true);
⦁ PHP – libxml2
– libxml_set_external_entity_loader(null);
⦁ NET -XmlTextReader
– reader.ProhibitDtd = true;
Bekijk de OWASP XXE Prevention cheatsheet voor mitigaties voor andere platforms. Tegenwoordig zijn de meeste bibliotheken beschermd tegen XXE aanvallen omdat het laden van externe entiteiten niet standaard is ingeschakeld.
Het gebruik van een lokale statische DTD kan veilige en correcte XML-invoer afdwingen. Een DTD-bestand definieert een aantal regels waaraan moet worden voldaan voordat de XML-invoer kan worden geladen. Zorg er ook voor dat de applicatie geen DTD’s van gebruikersinvoer accepteert.
Het kan ook een optie zijn om te kijken naar andere gegevensopslagformaten zoals YAML en JSON. Maar wees voorzichtig, deze formaten kunnen ook gevaarlijk zijn als ze niet op de juiste manier worden geïmplementeerd.