Schwachstellen in Zeilen-basierter Sicherheit

Es ist Zeit für einen weiteren Artikel zum Thema Sicherheit. Und durch einen Forum Thread zu „Datengesteuerter Sicherheit“ mittels der IS_MEMBER(), USER_NAME(), SUSER_SNAME() – Funktionen kam ich auf die Idee, ein kurzes Beispiel zu zeigen, wie sich solche Konstrukte leicht umgehen lassen und die geschützten/verborgenen Daten offengelegt werden können, wenn sie nicht mit weiteren Mitteln gesichert werden. Sehen wir uns ein Beispiel an.

Im Folgenden werden wir ein recht verbreitetes Szenario sehen, wie Sicherheit auf Zeilenebene / Row-Level Security (und auch Zellenebene/Cell-Level Security) implementiert werden kann.

Die Architektur ist recht einfach: Eine Tabelle enthält Datenzeilen, von welchen einige von einer bestimmten Gruppe Personen gelesen werden darf, und andere Zeilen von anderen Personen – jeweils exklusiv. Um das zu erreichen, wird eine Sicht angelegt. Diese Sicht muss natürlich denselben Besitzer haben, so dass der Prinzipal Berechtigungen auf die Sicht alleine erhalten kann, und durch die Besitzerkette an die Daten gelangt. Innerhalb der Sicht ist eine Where-Klause, die einen Filter auf ein bestimmtes Attribut in der Tabelle enthält, durch das der Benutzer der aktuellen Sitzung erkannt wird und ausschließlich die Daten zurückgeliefert werden, die seiner Rollen-Mitgliedschaft entsprechen. Natürlich gibt es auch komplexere Designs mit Zwischentabellen und mehrfachen Rollenmitgliedschaften/Rechten, aber am Ende teilen alle dieselbe Schwachstelle, die ich demonstrieren werde. Im Folgenden zunächst ein Diagramm der Architektur.

Sehen wir uns das ganze also an. Die Einrichtung Tabelle und der Sicht, inklusive 2er Beispieldatensätze:

Die Spalte „Role“ wird von der Sicht verwendet, um die jeweilige Zeile, unter Verwendung der IS_MEMBER()-Funktion, nur Mitgliedern der jeweils hinterlegten Datenbankrolle durchzureichen.

Benutzer, Rollen und Berechtigungen:

Erinnern wir uns, was die Tabelle enthält:

In einer heilen Welt, vor dem Sündenfall, wäre dies ausreichend. (Nachdem wir uns als „Andreas“, der Mitglied der Datenbankrolle RoleAlpha ist, einloggen) würden unsere Abfragen wie folgt aussehen, und lediglich die Zeilen zurückliefern, die der RoleAlpha „gehören“:

– Natürlich wird die Funktion User_Name() nur für Demo-Zwecke eingesetzt.

Ergebnis:

Angriff

Aber Andreas spielt nicht fair. Er ist neugierig, was sonst noch in der Tabelle stehen könnte. Also schreibt er eine Abfrage wie diese:

Und das Ergebnis ist:

Nicht „schön“, aber wir haben, was wir wollten: die „geschützten“ Daten.

Der bereits geschulte Leser erkennt diese Form des Angriffs vielleicht aus einem anderen Bereich wieder: SQL Injection.

Es ist eine Form des alten Freundes „Error Based Attack“ oder „Error Disclosure“, die auch bei schlecht geschriebenen Webanwendungen zum Zuge kommt. Das habe ich u.a. 2013 auf diversen Konferenzen gezeigt (Vortragsreihe). Der Kontext ist ein wenig anders, aber die Idee dahinter ist dieselbe.

Einigen kommt das Bild vielleicht schon bekannt vor 🙂

Stellt sicher, dass das nicht Euer Vorgarten ist!

Wo wir davon reden:

Schutzmaßnahmen

Was kann man gegen solche Angriffe tun? Im Wesentlichen stehen einem 3 bekannte Möglichkeiten zur Verfügung:

1) Einsatz von gespeicherten Prozeduren, die alle Fehler abfangen, oder, wenn man unbedingt mit Sichten Arbeiten möchte, der Einsatz einer dazwischengeschalteten Multi-Statement-Tabellenwertfunktion

2) Datenverschlüsselung (Nicht TDE!)

3) Ähnlich wie 1, Aufbau einer Mittelschicht in der Anwendung, die derartiges unterbindet.

Und schlussendlich sollte man für kritische Daten auch über eine Überwachungslösung nachdenken.

Die hier gezeigte Technik der Row-Level Disclosure ist nicht wirklich etwas Neues, wird aber gerne immer mal wieder vergessen. Nachlesen kann man darüber zum Beispiel auch in diesem (alten, aber immer noch zutreffenden) Whitepaper:

Implementing Row- and Cell-Level Security in Classified Databases Using SQL Server 2005



Happy securing,



Andreas


Wer sich ermuntert fühlt, nun einmal richtig in das Thema „Sicherheit mit SQL Server“ einzusteigen, für den habe ich auch 3 erstklassige Trainings im Angebot:

Für Beginner, die hier einen guten Überblick erhalten und grundlegende Kenntnisse erlernen:

(SES) SQL Server Security Essentials for Developers & Administrators (1 day) 3. April 2014 in Düsseldorf

Für Administratoren, die fortgeschrittene Sicherheitskonzepte umsetzen müssen:

(SIA) Securityworkshop for SQL Server Administrators (advanced) (1 day) 4. April 2014 in Düsseldorf

Für Entwickler, die fortgeschrittene Sicherheitskonzepte umsetzen müssen:

(SID) Securitysworkshop for SQL Server Developers (advanced) (1 day) 24. April 2014 in Düsseldorf

0 Kommentare

Hinterlasse einen Kommentar

An der Diskussion beteiligen?
Hinterlasse uns deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert