Unterschätzte IT-Sicherheitsgefahr durch SQL-Einschleusungen

Hackerangriffe können schwerwiegende Folgen haben: Der Angriff dieses Jahr auf die größte US-Benzin-Pipeline Colonial führte teilweise zu Benzin-Knappheit und langen Schlangen an Tankstellen – um nur ein Beispiel zu nennen. Für viele Unternehmen hat deshalb aktuell ein verbesserter Endpoint-Schutz oberste Priorität. Entwickler wissen jedoch genau: Sichere Endpoints sind wichtig – reichen aber allein nicht aus.

Auch ein Code, der fehlerhaft oder mit unzureichender Sicherheit programmiert wird, öffnet die Türen für mögliche Angriffe. Online-Sicherheitslücken sind ein sehr großes Problem, von dem selbst weltweit bekannte Technologieunternehmen betroffen sind. Bei Tesla beispielsweise gab es 2014 eine Sicherheitslücke bei der Funktion, mit der Kunden ihr Auto individuell anpassen können. Und beim Action-Spiel Fortnite waren 2019 die Daten von 80 Millionen Nutzern gefährdet. Apple bezahlte laut Berichten im vergangenen Jahr knapp 300.000 US-Dollar an Sicherheitsforscher, um Online-Schwachstellen aufzuspüren und zu beheben.

Zwar haben Sicherheitslücken in Webanwendungen vielfältige Ursachen, etwa Programmierfehler. Dennoch haben alle oben genannten Beispiele eines gemeinsam – und zwar eine sogenannte SQL-Einschleusung (SQL-Injection) . SQL (Structured Query Language) ist eine Standardsprache, mit der Datenbanken strukturiert und bearbeitet werden. Bei einer Einschleusung integrieren Angreifer fremde Befehle in die Datenbank, um etwa Daten einzusehen.

 

Am besten immer vom Schlimmsten ausgehen

SQL-Einschleusungen sind eine der gefährlichsten und gleichzeitig am weitesten verbreiteten Sicherheitslücken. Die gute Nachricht ist, dass man diese Gefahr verhindern kann, indem Unternehmen sich möglichst umfassend gegen solche Angriffe rüsten.

Im ersten Schritt sollten die verantwortlichen Teams sicherstellen, dass die Nutzerauthentifizierung nicht die einzige Verteidigungslinie ist. Diese Art der Authentifizierung ist zwar für die Benutzer sehr praktisch, aber als Sicherheitsmechanismus nicht ausreichend, da sie sich ganz einfach umgehen lässt. Angreifer können etwa den im Browser geladenen Javascript-Code ändern oder einen einfachen HTTP-Aufruf an das Backend in einer Client-Server-Architektur mit einem Parameter durchführen, der eine SQL-Einschleusung verursacht. Deshalb sollten Entwickler lieber auf Nummer sicher gehen und alle Informationen, die von einem Client gesendet werden, als potenziell schädlich betrachten. Die Authentifizierung sollte deswegen auf der Serverseite stattfinden – und zwar idealerweise so nah an der Quelle wie möglich. Entwickler sollten außerdem auch die jeweiligen Rechte von Datenbanknutzern genau auf dem Schirm haben. Alle SQL-Einschleusungen sind schädlich, aber manche sind noch gefährlicher als andere. Beispielsweise ist schon der reine Zugriff auf Nutzerdaten schlecht – wenn diese aber zusätzlich geändert oder gelöscht werden, ist es noch schlimmer.

Unternehmen sollten die Auswirkungen einer SQL-Einschleusung möglichst klein halten. Deshalb müssen Entwickler die Anwendungsberechtigungen für eine Datenbank vorab genau festlegen. Benötigt eine bestimmte Anwendung wirklich die Berechtigung, alle Datenbanken zu lesen, zu verändern und zu aktualisieren? Und ist es wirklich notwendig, dass eine Anwendung Tabellen ändern oder löschen kann? Diese relevanten Fragen müssen im Vorfeld geklärt werden. Es ist deshalb nicht ratsam, einfach pauschal jeder Anwendung freien Zugriff auf eine Datenbank zu gewähren. Genauso wenig sollte nur ein Datenbankbenutzer pro Anwendung autorisiert werden. Wenn es dagegen mehrere Nutzer mit jeweils individuellen Nutzerrollen gibt, ist die Datenbank besser geschützt. Genauso wie eine Brandschutztür einen Brand eindämmt, wird so verhindert, dass ein Angriff schnell auf die ganze Datenbank übergreift.

 

Parametrisierung ist die beste Verteidigung

Entwickler können die Sicherheit besonders durch vorbereitete Anweisungen und die Parametrisierung von Abfragen erhöhen. Viele Programmiersprachen verfügen über integrierte Funktionen zur Verhinderung von SQL-Einschleusungen: Wenn SQL-Abfragen geschrieben werden, wird dann eine vorbereitete Anweisung verwendet, die die Abfrage zusammenfasst.

Mit solchen vorbereiteten Anweisungen wird eine Abfrageparametrisierung durchgeführt, die die möglichen SQL-Anweisungen einschränkt: Entwickler erstellen eine Basisabfrage mit Platzhaltern, und die benutzerdefinierten Parameter werden dann zu diesen Platzhaltern hinzugefügt. Dies erhöht die Sicherheit entscheidend. Wenn eine vorbereitete Anweisung und parametrisierte Abfragen durchgeführt werden, erstellt die Datenbank dann zunächst einen Ausführungsplan für die Abfrage. Dies geschieht auf der Grundlage des Abfrage-Strings mit Platzhaltern, und die eventuell nicht vertrauenswürdigen Parameter werden an die Datenbank gesendet.

Da der Abfrageplan bereits erstellt ist, haben die Parameter keinen Einfluss mehr auf diesen und blockieren die Einschleusung vollständig. Vorbereitete Abfragen mit Parametrisierung sind daher die beste Verteidigung gegen eine SQL-Einschleusung.

Parametrisierung ist auch bei der Arbeit mit gespeicherten Prozeduren von größter Bedeutung. Selbst Profis glauben oft, dass mit gespeicherten Prozeduren SQL-Einschleusungen verhindert werden – aber das ist nicht immer der Fall. Wie jede SQL-Abfrage, die innerhalb einer Anwendung erstellt wird, kann auch eine gespeicherte Prozedur unerwünscht eingeschleust werden. Daher sollten Entwickler, genau wie bei SQL-Abfragen, die Abfragen in ihrer gespeicherten Prozedur parametrisieren, anstatt nur die Parameter zu verbinden.

In einigen Fällen sind vorbereitete Anweisungen jedoch nicht verfügbar. Manchmal unterstützen Programmiersprachen keine vorbereiteten Anweisungen, oder eine ältere Datenbank bietet nicht die Möglichkeit, die Eingaben der Nutzer als Parameter zu verarbeiten. In solchen speziellen Fällen kann dann die Eingabevalidierung durchaus eine akzeptable Alternative sein. Die verantwortlichen Teams sollten allerdings sicherstellen, dass die Eingabevalidierung auf einer Erlaubnisliste und nicht auf einer Black-List oder „Block-Liste“ beruht. Dafür braucht es eine gut gepflegte Bibliothek oder eine Regel, die alle zulässigen Muster beschreibt, z. B. mit einem regulären Ausdruck. Aber auch wenn vorbereitete Anweisungen möglich sind, ist eine Eingabevalidierung natürlich weiterhin nötig.

 

Mehrschichtige Sicherheit und strenge Kontrollen

Neben Parametrisierung und Eingabevalidierung gibt es aber noch mehr zu beachten: Zum Schutz vor Einschleusungen sollten Entwickler auch die Verwendung von objektrelationalen Abbildungen (ORM) in Betracht ziehen. Diese wandelt die Daten aus einer Datenbank in Objekte um – und umgekehrt. Dadurch werden explizite SQL-Abfragen, und damit das Risiko von SQL-Einschleusungen, verringert. Aber auch innerhalb der ORM-Bibliotheken kann es durchaus Schwachstellen geben, wenn etwa falsche oder veraltete Versionen von Sequelize oder Hibernate verwendet werden. Die sind sogenannte Klassenbibliotheken, mit denen ORM implementiert wird. Entwickler müssen also auf jeden Fall wachsam sein.

Brian Vermeer, Snyk

Welche Sicherheitsstrategien auch eingesetzt werden – eine genaue Kontrolle ist immer nötig, etwa um den Code zu überprüfen und eventuelle Schwachstellen zu erkennen. Code-Überprüfungen oder Programmieren in Paaren (Pair Programming) ermöglichen dies zwar, aber bei manuellen Kontrollprozessen gibt es immer auch eine gewisse Fehlergefahr. Für ein Höchstmaß an Sicherheit sollten Entwickler deshalb speziell entwickelte Scanning-Tools nutzen. Mit diesen können sie potenzielle Gefahren für SQL-Einschleusungen automatisiert erkennen, und sie werden benachrichtigt, wenn Schwachstellen in ihrem Code gefunden werden.

SQL-Einschleusungen stellen eine große Bedrohung dar – aber sie lassen sich abwehren. Mit einem Zero-Trust-Ansatz, vorbereiteten Anweisungen und Parametern sowie einer strengen Code-Überprüfung können Entwickler Einschleusungsversuche abwehren. Und gerade aktuell nehmen Cyberangriffe immer mehr zu. Deshalb ist es wichtiger denn je, dass Entwickler das Thema Sicherheit von Anfang an in ihren Code integrieren.

Brian Vermeer, Snyk