Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Achtung: Dies ist nicht der vollständige Artikel, sondern nur ein paar Seiten davon. Wenn Sie hier nicht erfahren, was Sie wissen möchten, finden Sie am Ende Informationen darüber, wie Sie den ganzen Artikel lesen können.

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

Gedrucktes Heft

Diesen Beitrag finden Sie in Ausgabe 1/2017.

Unser Angebot für Sie!

Lesen Sie diesen Beitrag und 500 andere sofort im Onlinearchiv, und erhalten Sie alle zwei Monate brandheißes Access-Know-how auf 72 gedruckten Seiten! Plus attraktive Präsente, zum Beispiel das bald erscheinende Buch 'Access 2010 - Das Grundlagenbuch für Entwickler'!

Diesen Beitrag twittern

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

Sie haben das Ende des frei verfügbaren Teils des Artikels erreicht. Lesen Sie weiter, um zu erfahren, wie Sie den vollständigen Artikel lesen und auf viele hundert weitere Artikel zugreifen können.

Sind Sie Abonnent?Jetzt einloggen ...
 

Kompletten Artikel lesen?

Einfach für den Newsletter anmelden, dann lesen Sie schon in einer Minute den kompletten Artikel und erhalten die Beispieldatenbanken.

E-Mail:

© 2003-2015 André Minhorst Alle Rechte vorbehalten.