Eingabeüberprüfung par Excellence Marc Ruef | 21.09.2009 Die technische Computersicherheit ist in den meisten Bereichen auf eine fehlerhafte Eingabeüberprüfung zurückzuführen. Dies bedeutet, dass ein Angreifer Daten an eine Applikation übergeben kann, die diese nicht oder so nicht erwartet hat und deshalb in unsicherer Weise weiterverarbeitet. Dies ist der Effekt, der bei den populären Angriffstechniken wie Pufferüberlauf, Format String, Cross Site Scripting, SQL-Injection und Directory Traversal beobachtet werden kann. Um dem entgegenzuwirken, müssen sämtliche Eingaben aus nicht-vertrauenswürdigen Quellen - in erster Linie jene, die vom Benutzer kommen - validiert werden. Oft sind die Entwickler zu nachlässig, alsdass sie diese Aufgabe vollumfänglich wahrnehmen würden. Dabei ist das Umsetzen von Eingabeüberprüfungen gar nicht so schwierig. Die verschiedenen Techniken, welche hierzu eingesetzt werden können, sollen nachfolgend illustriert werden. Als erstes sollte eine Eingabe auf ihren Typ hin untersucht werden. Dabei kann man sich weitestgehend an die Klassifizierung der Datentypen aus der Programmierung halten. Gerade das Erkennen von Zahlenwerten und der unterschiedlichen Subtypen (Ganzzahl, Fliesskommazahl) ist damit einfach und effizient. Wird eine Zahl erwartet und stattdessen ein String übergeben, können alleine anhand der Typenprüfung frühzeitig Massnahmen ergriffen werden. Wird eine Zahl erwartet und eine solche auch wirklich übergeben, kann der erwartete Wertebereich überprüft werden. Wird innerhalb einer Anwendung zum Beispiel mittels eindeutigen IDs auf Benutzer verlinkt, ist der zu erwartende Wertebereich wie folgt definiert: center(Eingabe >= Erste Benutzer-ID) UND (Eingabe =< Letzte Benutzer-ID)/center Ein Wert kleiner als der erste Benutzer und ein Wert grösser als der letzte Benutzer ist nicht legitim und kann sofort abgefangen werden. Dies bedingt natürlich, dass man sich der Spanne der erwarteten Werte bewusst ist. Dies ist in diesem Fall relativ einfach möglich, da zuvor die aktuellen Daten quergeprüft werden können. An anderer Stelle lässt sich gar mit statischen Werten arbeiten. Zum Beispiel erwartet die Minutenangabe einen Wert von 0 bis 59. Negative Werte sind dabei genauso wenig geduldet, wie Werte grösser als 59. Alternativ und ergänzend zur Analyse des Wertebereichs kann die Länge einer Eingabe geprüft werden. Dies ist vor allem bei Strings, bei denen kein Wertebereich wie bei Zahlen anhaftet, von Nutzen. Es soll wieder das Beispiel der Minutenangabe herangezogen werden. Die Länge derer beträgt entweder 1 (0 bis 9) oder 2 (10 bis 59). Bei Strings wird zum Beispiel erwartet, dass die korrekte Anrede in einem Brief entweder "Frau" oder "Herr" lautet und damit auf statische 4 Zeichen begrenzt ist. Etwas kniffliger wird es, wenn die Eingaben auf unerlaubte Zeichen hin untersucht werden. Dabei wird Zeichen für Zeichen durchgegangen, ob ein unerwünschtes Auftreten beobachtet werden muss. Am besten ist es, die erwünschten Zeichen zuvor in einer Whitelist zu spezifizieren. Jedes Zeichen, das nicht in dieser Liste vorkommt, wird als unerwünscht abgetan und damit die Weiterverarbeitung verhindert. Zum Beispiel wird innerhalb einer Telefonnummer lediglich die folgenden Zeichen erwartet: centerZeichensatz Telefonnummer = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /, " ", +)/center Es gibt Applikationen, die stellen Freifelder zur Verfügung, in denen Benutzer beliebige Eingaben tätigen können. Zum Beispiel in einem Webforum könnten Programmcodes abgedruckt werden, welche ansonsten unpopuläre Sonderzeichen enthalten. Dort kann nicht mehr einfach mit der Analyse einzelner Zeichen gearbeitet werden. Um dennoch Angriffsversuche als solche zu erkennen, kann versucht werden in einer Blacklist potentiell gefährliche Zeichenketten, welche innerhalb eines Angriffs genutzt werden müssten, zu erkennen. Dazu gehören zum Beispiel: centerBlacklist Pufferüberlauf = {aaaaaaaa, xxxxxxx, %20) Blacklist SQL Injection = {SELECT, UNION, WHERE, FROM, ORDER} Blacklist Directory Traversal = {C:\ , ..\, /etc/)/center Leider erzeugen solche generischen Filter für Zeichenketten eine Vielzahl an Falschmeldungen. Zum Beispiel könnte in dem genannten Forum das Problem in einer legitimen SQL-Abfrage diskutiert werden, was entsprechend die Blacklist SQL Injection auf den Plan rufen würde. Aus diesem Grund ist es anzuraten, zusätzlich oder alternativ die Struktur von Eingaben zu prüfen. Gehen wir davon aus, dass folgende Struktur als Eingabe erwartet wird. In den eckigen Klammern wird der Name der Daten, sowie durch Komma getrennt die Länge derer ausgewiesen. Der erste Wert user_id hat zum Beispiel eine Lännge von 1-3 Zeichen. centerEingabe A = user_id,1-3 + ";" + user_name,4-64 + ";"/center In der Eingabeüberprüfung kann nun anhand der statischen Werte analysiert werden, ob an Position 2-4 ein Strichpunkt verwendet wird. Denn schliesslich sind nur die folgenden Werte für user_id vorgesehen: centerEingabe A1 = 1;user1; Eingabe A2 = 10;user10; Eingabe A3 = 100;user100;/center Wird nicht wie erwartet an der gegebenen Position der Strichpunkt verwendet, handelt es sich bei den übergebenen Daten um ein nicht erwartetes Konstrukt. Damit können auf einer abstrakten Ebene unliebsame Eingaben identifiziert werden. Dies erfordert jedoch, dass man ein Prototyping der Datenkonstrukte anlegen kann. Ein umfassendes Verständnis für die Daten der Anwendung sind in diesem Fall erforderlich. Generell gilt es, dass bei einer Eingabeüberprüfung die erwarteten von den unerwünschten Eingabekonstrukten unterschieden werden. Dies ist nicht immer einfach, da der Entwickler bisweilen nur schwer abschätzen kann, welche individuellen Anforderungen die Endbenutzer haben könnten. Bei kleineren Projekten kann man das in etwa erahnen. Bei grossen Produkten, bei denen eine Vielzahl an Modulen und Entwickler zusammenarbeiten müssen, wird dies jenachdem schon fast ein Ding der Unmöglichkeit.