© saicle/Shutterstock.com
Wie angreifbar sind NoSQL-Datenbanken?

NoSQL, no SQL Injection - no Security?


Eine Datenbank ist für einen Angreifer fast immer interessant, denn meist enthält sie wertvolle Informationen, die er gerne hätte. Im Fall von SQL-Datenbanken versuchen die Angreifer im Allgemeinen, Daten über einen SQL-Injection-Angriff abzufragen. Davor schützt die Verwendung von Prepared Statements, die parametrisiert aufgerufen werden. Aber wie sieht es mit der Sicherheit von NoSQL-Datenbanken aus?

Die nahe liegende Folgerung „NoSQL => No SQL Injection => Keine Gefahr!“ können wir gleich zu Beginn streichen, denn NoSQL heißt ja nicht zwingend „No SQL“, sondern eher „Not only SQL“. Und wenn eine NoSQL-Datenbank (auch) SQL-Abfragen verwendet, ist natürlich SQL Injection möglich, vorausgesetzt vom Benutzer werden manipulierbare Parameter ungeprüft in eine anfällige SQL-Abfrage übernommen.

Injection, ganz ohne SQL

Wenn kein SQL für die Abfrage der Datenbank verwendet wird, ist unter Umständen ein mit einer SQL Injection vergleichbarer Angriff möglich. Generell gilt: Immer, wenn eine Abfragesprache verwendet wird, ist auch ein Injection-Angriff darauf denkbar. Statt SQL Injection könnten Angreifer es via JSON Injection, JavaScript Injection oder Ähnlichem versuchen (allgemein könnte man von einer „Query Language Injection“ oder „QL Injection“ sprechen [1]).

Betrachten wir mal MongoDB: Dort werden BSON oder JavaScript für Abfragen verwendet. Die Entwickler weisen in der Dokumentation auf die Gefahr von Benutzereingaben in JavaScript und durch das als Operatorkennzeichnung verwendete $-Zeichen hin [2].

Bei BSON-Abfragen sollte keine Gefahr bestehen, da die Abfragen als BSON-Objekte repräsentiert werden – aber nur, wenn die verwendete Programmiersprache und/oder Bibliothek alles richtig machen. Allerdings kennen Sie bestimmt den Spruch „Wenn das Wörtchen ‚wenn‘ nicht wär“? Denn wenn die Entwickler von Programmiersprache und/oder Bibliothek einen Fehler machen, ist es auch mit der Sicherheit von BSON nicht weit her. Genau so sieht es auch aus, wenn Programmiersprache und Datenbank nicht ganz die gleiche Sprache sprechen.

Phil Taylor hat schon 2010 einen Injection-Angriff auf MongoDB in Verbindung mit PHP beschrieben [3]. Der Angriff ist möglich, da PHP URL-Parameter in assoziative Arrays umwandeln kann, die MongoDB dann als Abfragen interpretiert. Der Angriff lässt sich ganz einfach verhindern, indem sichergestellt wird, dass alle Variablen vom erwarteten Type sind, in diesem Fall Strings. Aber dazu muss man erst mal wissen, dass ein falscher Type überhaupt ein Problem ist – und genau daran haperte es zumindest anfangs weitestgehend noch.

Nachdem der Angriff bekannt wurde, passte man das PHP-Handbuch entsprechend an [4]. Heutzutage sollte das also alles kein Problem mehr sein. Andererseits: Cross-site Scripting ist noch viel älter, und entsprechende Schwachstellen gibt es heutzutage immer noch. Sogar auf großen Websites wie zum Beispiel eBay, und sogar noch relativ lange nachdem die Angriffe bekannt gemacht worden waren [5]. Also: Augen auf beim Entwickeln und Implementieren!

Aber wieder zurück zu NoSQL und zurück in die Gegenwart. Wie sieht es aktuell mit der Sicherheit von NoSQL-Datenbanken aus? Am besten wissen das die Sicherheitsforscher, die ihre Ergebnisse regelmäßig auf den einschlägigen Konferenzen präsentieren. Gerade zum Thema NoSQL gab es in letzter Zeit ein paar interessante Vorträge.

Los ging es mit der DefCon 21, die im August 2013 stattfand. Dort hat Ming Chow vom Department of Computer Science der Tufts University unter den Titel „Abusing NoSQL Databases“ [6], [7] einen allgemeinen Überblick über die Sicherheit von NoSQL-Datenbanken gegeben. Wie es zumindest aus seiner Sicht damit aussieht, verrät die zweite Folie seiner Präsentation [7]: „Security of NoSQL databases? Weak, inconsistent, the wild wild west“. Warum das so ist, hat er mit einigen Beispielen demonstriert, auf die ich hier näher eingehen möchte.

Unsichere Default-Installationen

Alles, was ein Angreifer für einen Angriff wissen muss, ist (zu) oft der Datenbankhersteller, die IP-Adresse und die Nummer eines offenen Ports. Die bekannten Default-Ports verschiedener Datenbanken zeigt Tabelle 1.

Datenbankhersteller

Port(s)

MongoDB

27017, 28017, 2708

CouchDB

5984

HBase

9000

Cassandra

9160

Neo4j

7474

Redis

6379

Riak

8098

Tabelle 1: NoSQL-Datenbanken und ihre Default-Ports

Wenn Sie eine der Datenbanken mit offenem Default-Port betreiben, haben Sie dafür hoffentlich einen Administrator oder Benutzer mit Authentifizierung konfiguriert. Denn per Default ist das nicht unbedingt der Fall. Selbst wenn es Benutzer gibt, sind deren Passwörter jedoch nicht unbedingt sicher gespeichert: MongoDB verwendet das unsichere Hash-Verfahren MD5, Redis speichert die Passwörter sogar gleich als Klartext, CouchDB verwendet entweder Klartext oder einen schwachen Salt-Wert.

Weitere Kritik- und gleichzeitig Ansatzpunkte für einen Angreifer sind die in Klartext erfolgende Kommunikation mit dem Client, das Fehlen von Datenbankverschlüsselung und Auditing-Möglichkeiten sowie allgemein die Betonung der „vertrauenswürdigen Umgebung“ für die Datenbank. Zumindest Datenbanken im Webumfeld sollten sich besser nicht darauf verlassen.

Eigentlich müsste inzwischen überall der Grundsatz des „Secure by Default“ gelten, und wenn das nicht so ist, muss zumindest der Betreiber der Datenbank für deren Sicherheit sorgen können. Was im Fall von ­No­SQL-­­Datenbanken mangels entsprechender Funktionen mitunter nicht ganz einfach ist.

Neue Klassen von Injection-Angriffen

Als weiteren Kritikpunkt führt Ming Chow die mit den NoSQL-Datenbanken entstehenden und schon oben erwähnten neuen Injection-Angriffe auf. Seine Beispiele:

  • Beim Einfügen eines Eintrags in ein nicht existierendes Schema wird dieses Schema neu angelegt.

  • Durch die Verknüpfung von Strings können unsichere Anfragen erzeugt werden. Wir erinnern uns: SQL-Abfragen lassen sich durch den parametrisierten Aufruf von Prepared Statements sehr einfach verhindern.

  • JavaScript-Funktionen können db.eval() und $where-Klauseln als Parameter enthalten.

Heterogenität ist (k)ein Problem

Den nächsten Kritikpunkt überschreibt Ming Chow mit „A Heterogeneous Problem“: Entwickler und Admins müssen für jedes Datenbanksystem die Dokumentation lesen („RTFM for each database system“), die Systeme unterscheiden sich in

  • Terminologien und Analogien

  • Methoden zur Vergabe von Rechten und Benutzerkontrolle

  • ihren Abfragetypen, zum Beispiel Cassandra Query Language (CQL), befehlsbasierten Abfragen, JavaScript

  • ihren Ergebnistypen, zum Beispiel JSON, Binary JSON (BSON)

Das stimmt alles – aber auf Basis dieses Arguments ist auch PHP unsicher – und jede andere Programmiersprache. Denn davon gibt es auch ziemlich viele, und etliche davon unterscheiden sich gewaltig. Aber kommen wir zurück zu den Datenbanken. Natürlich ist SQL stark standardisiert, die verschiedenen Implementierungen unterscheiden sich kaum. Allerdings gibt es mitunter eben doch entscheidende Kleinigkeiten, die voneinander abweichen. Deswegen muss auch dort immer die Dokumentation ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang