XPath Injection
Angriffsmöglichkeiten auf XML gibt es Reihenweise: von
XML Document Size/Width/Depth Attacks über
Wellformedness-based Paser Attacks bis hin zu diversen
Injections. Allgemein bekannt sind nur relativ wenige dieser Angriffe. Oftmals ist übrigens nicht XML selbst an den Angriffsmöglichkeiten Schuld, in vielen Fällen lässt einfach der Parser zu viel zu und bietet zu viele, per Default immer aktive, Erweiterungsmöglichkeiten an. Wie bei vielen anderen Anwendungen wäre es auch hier sicherer, per Default alles abzuschalten und gewünschte Features vom Entwickler explizit aktivieren zu lassen.
Der Name
XPath Injection erinnert jedoch nicht von ungefähr an die allgemein bekannte (und seit vielen Jahren vermeidbare aber dennoch noch häufig angetroffene)
SQL Injection. Geht es doch auch bei der XPath Injection um den unberechtigten Zugriff auf eigentlich geschützt geglaubte (XML) Daten. Und genauso wie bei der SQL Injection existiert eine einfache Lösung:
Parameterized XPath Expressions. In Kombination mit einer Whitelist, die nur die absolut notwendigen Benutzereingaben zulässt, und der
Validierung ALLER Benutzereingaben ist man damit fast immer auf der sicheren Seite (ein Restrisiko bleibt immer).
Nehmen wir als Beispiel das folgende XML
(OK, das mit dem Passwort ist relativ unrealistisch), das als einzelnes XML-Dokument gespeichert auf dem Datenträger vorliegt:
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user username="John Doe" password="JohnSecret">
<salary>1500 €</salary>
</user>
<user username="Jane Doe" password="JaneSecret">
<salary>1800 €</salary>
</user>
<user username="Dummy" password="DummySecret">
<salary>5000 €</salary>
</user>
</users>
Um nun das Gehalt eines Mitarbeiters zu ermitteln muss neben dem korrekten Benutzernamen auch das passende Passwort eingegeben werden. Ein erwarteter XPath Ausdruck kann damit so aussehen:
/users/user[@username='Jane Doe' and @password='JaneSecret']/salaryDie Auswertung dieses Ausdrucks ergibt wie erwartet 1800 €, falsche Benutzernamen und/oder Passwörter führen zu einem leeren NodeSet.
Dieser Ausdruck wird nun dynamisch in einer Applikation zusammengestellt. Die XPath Injection selbst ist von der Programmiersprache unabhängig und kann in den meisten Programmiersprachen zum Problem werden.
username und
password sind hier gewöhnliche Textfelder, die ohne Validierung direkt in den XPath Ausdruck übernommen werden:
/users/user[@username='username.getText()' and @password='password.getText()']/salaryEin Angreifer würde jetzt mit dem Spielen beginnen und als Passwort vielleicht
' or 1 = 1 or ' eingeben. Der Benutzername ist dabei völlig egal. Und siehe da, die Auswertung ergibt drei Rückgabewerte: 1500 €, 1800 € und 5000 €. Oh oh. Doch das Spiel geht weiter.
Bisher haben wir ja nur alle Gehälter zurückbekommen, wer wie viel verdient wissen wir ebenso wenig wie was sonst noch so im XML-Dokument an Informationen enthalten ist. Mit '] | /* | /foo[bar=' als Benutzernamen und einem leerem Passwort lässt sich das schnell ändern.
Diese verschärfte Variante nennt sich übrigens
Blind XPath Injection, dabei benötigt der Angreifer nicht einmal mehr Kenntnisse des XML und kommt je nach XPath (Injection) an das vollständige Dokument heran. Dazu muss er nur ein bisschen herumprobieren und dabei aus den verwendeten Anführungszeichen (einfache oder doppelte) sowie den eckigen Klammern ausbrechen. Wie bei der SQL Injection kann man auch hier auf gesammelte Erfahrungen zurückgreifen und einmal funktionierendes wiederverwenden…
Bis hierhin könnte ein Entwickler nun denken, „Toll, dann bekommt ein Angreifer eben das gesamte XML-Dokument zurück, kritische Informationen sind ohnehin keine enthalten“… Zugegeben, das obige Beispiel mit den Gehaltsinformationen ist künstlich, und XML-Dokumente mit Benutzername/Passwort (im Klartext) zur Authentifizierung dürften kaum verbreitet sein?!Allerdings ist XPath Bestandteil vieler weiterer XML Standards, von
XForms über
XSLT bis hin zu
XQuery. XQuery ist die Abfragesprache für XML, mit der auch der Datenbankzugriff möglich wird. Seit einigen Monaten existiert auch
XQuery Update Facility als Candidate Recommendation, womit auch der standardisierte Schreibzugriff auf die DB in greifbare Nähe gerückt ist. Der kommende W3C Standard wird von der
IBM DB2 9.5 bereits unterstützt, andere Datenbanken werden mit Sicherheit folgen.
Glücklicherweise gibt es noch keine Möglichkeit, mit XQuery Update Facility ganze Tabellen zu löschen oder gar ein
drop database auszuführen. Außerdem wird, zumindest von der DB2, in XQuery Statements nicht der volle XPath Standard unterstützt, d.h. man ist auf bestimmte Achsen beschränkt und kann nicht von einem tiefer liegenden Element wieder aufs Wurzelelement zurückspringen. Ob das immer so bleiben wird ist allerdings fraglich.
Verhindern kann man die XPath Injection, neben der Validierung aller Benutzereingaben, durch Verwendung von
Parameterized XPath Expressions, die, analog zu den
Prepared Statements in SQL, einen Ausbruch aus dem Daten- in den Befehlsbereich verhindern. Der XPath Ausdruck sieht im XSL als solchermaßen parametrisierter Ausdruck dann z.B. so aus:
/users/user[@username=$username and @password=$password]/salaryDie beiden Parameter werden auf dem üblichen Weg direkt im Stylesheet mit Werten gefüllt. Ein Angreifer beißt sich daran, zumindest nach derzeitigem Kenntnisstand, mit den oben beschriebenen Angriffen die Zähne aus, das XML-Dokument bleibt unerreichbar. Zum Zeitpunkt der Auswertung ist bei Parameterized XPath Expressions der XPath bereits interpretiert; egal welche Eingabe, der Angreifer kommt nicht mehr aus dem Datenbereich heraus.
Jetzt liegt es an den Entwicklern, XPath Ausdrücke mit
Parameterized XPath Expressions zusammenzustellen und gleichzeitig eine vollständige
Whitelistüberprüfung zu integrieren. Das jahrelange Debakel wie bei SQL Injections bleibt XML damit vielleicht erspart.