Sichere Filterausdrücke

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

Sichere Filterausdrücke

Filterausdrücke können schnell gefährlich werden, zumindest wenn Sie nicht aufpassen. Dafür sorgt die sogenannte SQL-Injection, bei der davon ausgegangen wird, dass der Benutzer einen Ausdruck in die Benutzeroberfläche eingibt, die dann als Teil eines SQL-Ausdrucks verwendet wird und Schaden anrichten könnte. Dieser Beitrag erläutert, was SQL-Injection eigentlich ist und wie Sie sich dagegen wappnen können.

Die SQL-Injection ist eine Methode, aus eigentlich harmlosen SQL-Anweisungen schädliche SQL-Anweisungen zu machen – oder damit an Informationen zu gelangen, die der Benutzer normalerweise nicht erhalten sollte. Dabei ist die Voraussetzung immer ein Eingabefeld in einer Webseite oder, in diesem Falle, in einem Access-Formular, in das der Benutzer beispielsweise einen Vergleichswert für einen Vergleichsausdruck eingeben soll – im einfachsten Fall etwa die ID eines Kunden.

Beispielformular

Als Spielwiese für die folgenden Beispiele verwenden wir ein einfaches Access-Formular namens frmKunden samt Unterformular sfmKunden, wobei das Unterformular die Daten der Tabelle tblKunden anzeigt und das Hauptformular ein Eingabefeld für einen Suchbegriff liefert, der zunächst die Suche nach Werten im Feld KundeID ermöglicht (s. Bild 1).

Beispielformular in der Entwurfsansicht

Bild 1: Beispielformular in der Entwurfsansicht

Für das Textfeld txtKundenID legen wir die folgende Ereignisprozedur an:

Private Sub txtKundenID_AfterUpdate()
     Dim strSQL As String
     strSQL = "SELECT * FROM tblKunden WHERE KundeID = "  & Me!txtKundenID
     Me!sfmKunden.Form.RecordSource = strSQL
End Sub

Diese sorgt dafür, dass eine neue SQL-Anweisung zusammengestellt wird, die den Datensatz der Tabelle tblKunden mit einem bestimmten Wert im Feld KundeID liefert und diesen der Eigenschaft RecordSource des Unterformular zuweist. Dies gelingt auch reibungslos, wenn der Benutzer einfach nur einen Zahlenwert eingibt (s. Bild 2).

Filtern nach dem Wert 1 im Feld KundeID

Bild 2: Filtern nach dem Wert 1 im Feld KundeID

Ergebnismenge mit UNION erweitern

Was an unserer Methode soll also gefährlich sein – schließlich kann man doch nur Zahlenwerte eingeben und erhält das gewünschte Ergebnis? Mitnichten: Schon die Kenntnis der Datenstruktur (oder ein wenig experimentelle Arbeit) erlauben es, ein ganz anderes Ergebnis zu erhalten als geplant. Geben Sie beispielsweise einmal den folgenden Ausdruck in das Suchfeld ein:

1 UNION SELECT * FROM tblKunden WHERE KundeID = 10

Das Ergebnis ist überraschend: Es gibt keinen Fehler, sondern es erscheinen zwei Datensätze (s. Bild 3)! Allzu verwunderlich ist dies jedoch gar nicht, denn der resultierende Ausdruck in der Variablen strSQL, den Sie sich einfach im Debugbereich ausgeben lassen können, sieht wie folgt aus:

Erweiterung des Ergebnisses per UNION

Bild 3: Erweiterung des Ergebnisses per UNION

SELECT * FROM tblKunden WHERE KundeID = 1 
UNION 
SELECT * FROM tblKunden WHERE KundeID = 11

Gut, der Schaden ist gering, denn wir greifen so nur auf Datensätze zu, die wir auch anderweitig hätten lesen können. Aber wenn wir keine Bedingung angeben, liefert der resultierende SQL-Ausdruck uns sogar wieder alle Datensätze:

SELECT * FROM tblKunden WHERE KundeID = 1 
UNION 
SELECT * FROM tblKunden

Dies könnte interessant werden, wenn der eigentliche Filterausdruck noch dafür sorgt, dass beispielsweise nur die Kunden des aktuell angemeldeten Mitarbeiters angezeigt werden sollen.

Daten anderer Tabellen auslesen

Noch spannender wird es, wenn Sie hinter dem UNION -Schlüsselwort nicht auf die gleiche, sondern direkt auf eine andere Tabelle zugreifen, die unter Umständen kritische Daten enthält. Im Beispiel wollen wir einfach einmal probieren, Daten aus der Tabelle tblArtikel zusätzlich auszugeben, und testen den folgenden Suchausdruck:

1 UNION SELECT ArtikelID as KundeID, Artikelname as Kundencode FROM tblArtikel

Dies liefert im ersten Anlauf noch den Fehler aus Bild 4, weil der zweite Teil der UNION-Abfrage nicht die gleiche Anzahl Felder wie der erste Teil zurückliefert. Aber was geschieht, wenn wir einfach ein paar fixe Werte entsprechend der Anzahl der Felder des ersten Teils der Abfrage hinzufügen – und so notfalls durch Experimentieren auf die richtige Anzahl Felder kommen? So ergibt sich nach kurzem Test der folgende Ausdruck:

Fehler, wenn nicht alle Seiten der UNION-Abfrage die gleiche Anzahl Felder enthalten

Bild 4: Fehler, wenn nicht alle Seiten der UNION-Abfrage die gleiche Anzahl Felder enthalten

1 UNION SELECT ArtikelID as KundeID, Artikelname as Kundencode, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 FROM tblArtikel

Das Ergebnis ist einigermaßen erschreckend: Wir gelangen so tatsächlich an die Informationen der Tabelle tblArtikel, die eigentlich gar nicht zur Datenherkunft des Unterformulars gehört (s. Bild 5). Und natürlich könnten wir diese Tabelle auch durch eine Tabelle mit wirklich sensiblen Daten wie etwa der Benutzertabelle ersetzen.

Ermitteln der Daten einer anderen Tabelle

Bild 5: Ermitteln der Daten einer anderen Tabelle

So lassen sich auch leicht die Tabellen einer Datenbank ausgeben – und zwar mit diesem Suchbegriff:

1 UNION SELECT Name, Type , 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 FROM MSysObjects WHERE Type = 1

Gefährliche Strings

Gibt es ebenfalls Probleme, wenn man ein Suchfeld für die Eingabe einer Zeichenkette verwendet? Ja. Dazu fügen wir dem Formular ein Textfeld namens txtFirma hinzu, das nach dem Aktualisieren die folgende Ereignisprozedur auslöst:

Private Sub txtFirma_AfterUpdate()
     Dim strSQL As String

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zahlenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Aktuell im Blog
Onlinebanking mit Access

Es ist geschafft: Endlich ist das Buch Onlinebanking mit Access fertiggeschrieben. Das war... [mehr]

Direktzugriff auf Tabellen und Felder

Die IntelliSense-Erweiterung für Tabellen und Felder hat mir soviel Spaß gemacht, dass ich gleich... [mehr]

IntelliSense für Tabellen und Felder

Wenn Sie mit dem VBA-Editor arbeiten und dort gelegentlich SQL-Anweisungen eingeben, müssen Sie... [mehr]

Download Access und SQL Server

Erfahren Sie, welche Schritte zum Download des aktuellen Stands des Buchs "Access und SQL Server"... [mehr]

Bilder in Access 2013

Wer die Bibliothek mdlOGL0710 von Sascha Trowitzsch oder ein ähnliches Modul aus meinen... [mehr]

Dynamische Ribbons

Immer wieder fragen Leser, wie man Ribbon-Elemente wie etwa Schaltflächen in Abhängigkeit... [mehr]

Die Blogmaschine

Einen kleinen Blog zusätzlich zum Shop zu betreiben ist eine tolle Sache. Hier lassen sich... [mehr]

Wegwerfadressen für die Newsletteranmeldung

Die Verwendung von Wegwerf-Adressen für die Nutzung aller möglichen Online-Dienste nimmt... [mehr]

Access und Facebook

Facebook und Access - das ist eine der wenigen Kombinationen, die ich noch nicht in die Mangel... [mehr]

Access und SQL Server - das Projekt

Mein neues Buch Access und SQL Server (gemeinsam mit Bernd Jungbluth) geht in die Endphase. Wer... [mehr]