Security through obscurity

20. Juli 2012 um 18:24 Uhr von Wolfgang Stengel zu Programmierung
Wenn man Anwendungen programmiert die einem breiten Publikum zugänglich sind und/oder sicherheitssensitive Informationen verwalten muss natürlich auf Sicherheit geachtet werden. Dabei hat sich herauskristallisiert dass "Security through obscurity", also das "absichern" der Anwendung durch Verschleierung und Täuschung, zwar in vielen Fällen einfach zu machen, aber dennoch keine gute Idee ist.

Ein einfaches Beispiel ist eine Drucken-Funktion die nach einer Registrierung oder Bestellung greift. Der Kunde gibt seine Daten ein, schliesst die Transaktion ab und bekommt auf der Folgeseite die eingegebenen Informationen noch einmal angezeigt, um sie z.B. Drucken zu können. Nehmen wir also an die URL lautet folgendermassen:

http://eingekauft.de/confirmation.php?orderid=2983

Ohne Absicherung könnte jeder Nutzer die ID im GET-Parameter verringern und damit andere Nutzer, die vor ihm bestellt haben, ausspionieren. Die Seite soll auch als Bookmark später noch funktionieren, also scheidet eine Absicherung über die Session oder über ein Cookie aus. Ein weiterer Parameter schafft Abhilfe: Es wird eine Zahl oder allgemein ein Code angehängt, über den die ID validiert werden kann:

http://eingekauft.de/confirmation.php?orderid=2983&code=2387124091823

Die Anwendung muss dann auf irgend eine Weise zuverlässig feststellen können ob der Code zur ID passt, und falls dies nicht der Fall ist, die Anfrage ablehnen. Dadurch wird "spielen" mit der ID verhindert. Ein Angriff ist dann nur noch durch eine Brute Force-Attacke möglich, was jedoch bei einem genügend langen Code und einer Sicherung gegen zuviele Hits in kurzer Zeit kein Thema ist.

Doch woher kommt dieser Code? Es gibt zwei Möglichkeiten:
  • Möglichkeit 1: Man entwirft einen Algorithmus mit dem der Code aus der ID und/oder einem anderen Teil der Daten des Users erzeugt wird. Die Anwendung muss dann nichts weiter tun als beim Aufruf der Seite die ID (und/oder dazugehörige Daten) erneut durch den Algorithmus laufen zu lassen und das Ergebnis mit dem im GET-Parameter übergebenen Code zu vergleichen. Ein einfaches Beispiel: Der Code besteht aus den Nachkommastellen des Sinus der ID.
  • Möglichkeit 2: Man verwendet keine dem User bekannte Information. Die einfachste Variante wäre eine Zufallszahl. Den so gewonnenen Code speichert man zum zur ID gehörenden Datensatz ab. Beim Aufruf der Seite vergleicht die Anwendung den übergebenen Code mit dem in der Datenbank.
Die erste Methode wäre dann ein klassisches Security by obscurity-Problem, da sie nur darauf basiert dass der Angreifer den Algorithmus zur Berechnung des Codes aus der ID nicht kennt. Dadurch wäre ein Reverse Engineering-Angriff denkbar, bei dem man mehrere Bestellungen erzeugt und aus den dadurch gewonnenen ID/Code-Paaren den geheimen Algorithmus herleitet. Hat man diesen ermittelt so können Codes direkt aus frei gewählten IDs selbst erstellt und dadurch alle Benutzerdaten ausspioniert werden.

Bei der zweiten Methode hat der Code nichts mit der ID oder den Benutzerdaten zu tun und der Angreifer gewinnt durch Experimente keine hilfreichen Erkenntnisse. Vorraussetzung hierfür ist natürlich dass der Zufallsgenerator einen ordentlichen Anfangswert (Seed) verwendet. Theoretisch ist auch hier ein Angriff denkbar, da die meisten Zufallsgeneratoren deterministisch sind, jedoch hängt der Code nicht mehr von dem Angreifer bekannten Daten ab, was Reverse Engineering praktisch unmöglich macht.
PHP Wolfgang Stengel