Montag, 1. März 2010


Topthema

Donnerstag, 22. Januar 2009 | Topthema

About Security #189: Schwachstellen-Suche: XPath-Injection

(Link zum Artikel: http://www.entwickler.de/entwicklerde/kolumnen/046968)

In dieser Folge geht es weiter um die in About Security #188 beschriebenen XPath-Injection-Schwachstellen: Sie erfahren, was Blind XPath-Injection ist und wie Sie die Schwachstellen finden und verhindern können.

Blind XPath-Injection

Sind keine Informationen über die XML-Datei bekannt, kann vergleichbar dem Vorgehen bei der Blind SQL-Injection (siehe About Security #175) eine Blind XPath-Injection durchgeführt werden. XPath erlaubt Schritte relativ zum aktuellen Knoten, so dass die Namen der weiteren Knoten nicht bekannt sein müssen, um darauf zuzugreifen. Außerdem können Meta-Informationen wie der Name eines bestimmten Elements abgefragt werden. Im Kombination erlaubt das das Ermitteln der Namen und Werte aller Knoten des Dokuments, ohne das vorher Informationen über seine Struktur oder die Inhalte bekannt sind.

Als Beispiel soll eine XPath-Injection-Schwachstelle dienen, die nur True/False-Fragen zulässt. Um z.B. den Namen des Elternknotens des aktuellen Knotens zu ermitteln, kann eine Folge von Eingaben nach folgendem Muster verwendet werden, um das erste Zeichen des Namens zu ermitteln:

' or substring(name(parent::*[position()=1])),1,1)='a
' or substring(name(parent::*[position()=1])),1,1)='b
' or substring(name(parent::*[position()=1])),1,1)='c
...

Je nachdem, ob der erste Buchstabe ein a, b, c,... ist, wird dann entweder das Ergebnis für True oder für False zurückgeliefert. Für den zweiten Buchstaben werden dann Eingaben nach dem Muster

' or substring(name(parent::*[position()=1])),2,1)='a

usw. verwendet, und immer so weiter, bis der Name des Elternknotens bekannt ist. Davon ausgehend kann dann entsprechend der Rest des Dokuments ermittelt werden.

XPath stellt noch einige weitere Funktionen bereit, die im Rahmen des Angriffs hilfreich sind:

count()
liefert die Anzahl der Kindknoten eines übergegebenen Elements zurück. Damit kann ermittelt werden, über welchen Bereich die position()-Werte iteriert werden müssen
string-length()
liefert die Länge eines übergegebenen Strings zurück. Damit kann ermittelt werden, über welchen Bereich die substring()-Werte iteriert werden müssen.
SQL-Injection oder XPath-Injection?
About Security: Die komplette Serie

Viele der Testeingaben für die Suche nach SQL-Injection-Schwachstellen führen im Fall einer XPath-Injection zu einem Fehler oder einem ungewöhnlichen Verhalten der Anwendung. So machen z.B. die beiden Eingaben

'
'--

die XPath-Query ungültig und führen zu einem Fehler, und eine oder mehrere der Eingaben

' or 'a'='a
' and 'a'='b
or 1=1
and 1=2

führen zu einer Änderung im Verhalten der Anwendung. Falls also eine mögliche SQL-Injection-Schwachstelle nicht ausgenutzt werden kann, könnte es sich um eine XPath-Injection-Schwachstelle handeln.

Testmuster für XPath-Injection

Für Parameter, die beliebige Eingaben erlauben, können z.B. die folgenden beiden Testmuster verwendet werden:

' or count(parent::*[position()=1])=0 or 'a'='b
' or count(parent::*[position()=1])>0 or 'a'='b

Für numerische Parameter können z.B. folgende Testmuster verwendet werden:

1 or count(parent::*[position()=1])=0
1 or count(parent::*[position()=1])>0

Ändert sich das Verhalten der Anwendung bei Eingabe des Testmusters, ohne einen Fehler zu erzeugen, ist wahrscheinlich XPath-Injection möglich.

Ist das der Fall, könnte z.B. mit Eingaben nach dem Muster von oben der Name des Elternknotens Zeichen für Zeichen ermittelt werden:

substring(name(parent::*[position()=1])),1,1)='a'
substring(name(parent::*[position()=1])),1,1)='b'
...

für das erste Zeichen des Namens usw. usf.

Ist der Name des Elternknotens bekannt, kann davon ausgehend der Rest des XML-Baums abgefragt werden. Um zu prüfen, ob XPath-Injection überhaupt möglich ist oder nicht, ist das aber nicht mehr nötig. Dafür reicht es schon, wenn z.B. der Name des Elternknotens ermittelt werden kann.

XPath-Injection verhindern

Für den Schutz vor XPath-Injection gibt es die gleichen Möglichkeiten wie für den Schutz vor SQL-Injection (siehe About Security #12/ 13 und #176: Die Verwendung parametrisierter Abfragen und die Filterung der Eingaben.

Im Gegensatz zu den meisten Datenbanken kennt XPath selbst keine parametrisierten Abfragen, sie werden aber von verschiedenen APIs wie z.B. XQuery bereit gestellt. Sofern verfügbar, sind sie der beste Schutz vor XPath-Injection. Stehen parametrisierte Abfragen nicht zur Verfügung, müssen alle Benutzereingaben geprüft und unerwünschte Eingaben verworfen werden. Beim ebenfalls möglichen Ausfiltern gefährlicher Zeichen besteht wie immer die Gefahr, dass die Filter ausgetrickst werden können.

Am besten wird die Eingabe anhand einer Whitelist mit zulässigen Werten geprüft. Ist das nicht möglich, kann evtl. ein Whitelist zulässiger Zeichen verwendet werden, die am besten nur alphanumerische Zeichen enthält. Als letzte Möglichkeit bleibt das Prüfen auf die gefährlichen Zeichen ( ) [ ] = : ' , * / und alle Whitespace-Zeichen wie Leer- und Tabulatorzeichen, da drüber die XPath-Abfrage manipuliert werden kann.

In der nächsten Folge geht es weiter um das Einschleusen von Befehlen, und zwar in SOAP.

Wenn Sie Fragen oder Themenvorschläge haben, können Sie diese gerne an die angegebene E-Mail-Adresse senden oder im Security-Forum einbringen!

Carsten Eilers

Kommentare

Folgende Links könnten Sie auch interessieren