Funktionstrennung (Separation of Duties) und rollenbasierte Sicherheitskonzeption im SQL Server

Autor: Andreas Wolter

Veröffentlicht: 7. Dezember 2017

Betrifft: SQL Server 2016-2017

Einführung

Mit der anstehenden Umsetzung des Datenschutz-Grundverordnung (DSGVO) (European General Data Protection Regulation/GDPR) im Mai 2018 schreibt es im Grunde das Gesetz vor, ein Sicherheitskonzept zu haben. Microsoft SQL Server, genau wie andere Datenbanksysteme, enthält die wichtigsten Werte, die es zu schützen gilt: die Daten selbst. Deshalb ist es Zeit für einen Artikel aus einer strategischeren Perspektive in Bezug darauf, wie ich SQL Server und seine Daten schütze.

Beim Design für Sicherheit gibt es mehrere bekannte Sicherheitsprinzipien in der IT-Technologie. Die gängigsten, und das sind die, die ich beachte, wenn ich für Sicherheit designe, sind wahrscheinlich die folgenden:

  • Least Privilege
  • Funktionstrennung ( = Separation / Segregation of Duties)
  • Rekonstruktion von Ereignissen
  • Delegation von Befugnissen
  • Realitätschecks
  • Externe Inspektion
  • Gültige Transaktionen
  • (Kontinuität des Betriebs)

Die ersten zwei können als sehr eng zusammenhängend und einander ergänzend betrachtet werden, wenn es um die Umsetzung geht, und bilden das Hauptthema dieses Artikels.

Funktionstrennungs- und Least Privilege Sicherheitsprinzipien

Das Prinzip von “Least Privilege” bedeutet im Grunde, dass Nutzer nicht mehr Privilegien haben sollten als nötig, um ihre täglichen Aufgaben zu erfüllen. Um Daten und das System allgemein vor potentiellem Schaden zu sichern, ist es wichtig, eine umfassende Hierarchie von Nutzern und getrennten Funktionen festzulegen und jede Person mit seiner eigenen Nutzer-ID und so minimalen Befugnissen wie möglich auszustatten, um ihre täglichen Aufgaben zu erfüllen.
Das wird auch “Separation of Duties” oder “Segregation of Duties” genannt.

DAC vs. MAC

In der Microsoft SQL Server-Domäne wird ein rollenbasiertes Sicherheitskonzept im Allgemeinen zur Umsetzung des obengenannten verwendet. Es verstärkt die Sicherheit unter Nutzung des GRANT/DENY-Systems von SQL Server, ein Konzept, welches auch als Discretionary Access Control (DAC) bekannt ist.

Ein anderes gängiges Konzept, was besonders in Regierungsbehörden verwendet wird, ist die label-based access control (LBAC)/Security (Labelbasierte Sicherheit).

Label-based Security kann mittels Zeilen- und Zell-Ebenen-Sicherheit unter Verwendung von Technologien wie Always Encrypted und Row Level Security (RLS) in SQL Server umgesetzt werden. Sie erlaubt eine feinere Kontroll-Ebene als die der Discretionary Access Control und funktioniert durch die Klassifizierung von Daten, und ist auch bekannt als Mandatory Access Control (MAC).

Label-based Security wird in diesem Papier nicht weiter behandelt. Ich empfehle das Whitepaper Implementing Row- and Cell-Level Security in Classified Databases zum Einstieg. Obwohl es auf SQL Server 2008 basiert, gibt es die Gedanken hinter diesem Konzept gut wieder.

Rollenbasierte Sicherheit

Was die rollenbasierte Sicherheit angeht, sollte angemerkt werden, dass niemand vom Prinzip der „least privilege“ ausgenommen ist. Es trifft nicht nur auf die Endnutzer der Datenbankanwendung zu, sondern schließt auch Administratoren, Support-Personal und sogar Entwickler mit ein. Meiner Ansicht nach ist es einfacher, eine sichere Datenbank zu entwickeln, wenn die Entwickler und DBAs nur ein Konto verwenden, das ihnen genügend Rechte für die Rolle gibt, die sie einnehmen, was als das Verwenden des “least-privileged user account” bezeichnet wird.
Mit anderen Worten, „rollenbasierte Sicherheit“ heißt nicht nur:

User= [“hat”] Role

sondern vielmehr:

User1 + TaskA = [“nimmt an”]  RoleA

und

User1 + TaskB = [“nimmt an”] RoleB

Manchmal ist es hilfreich, es zu visualisieren:

D.h. DBAs sollten nur die SysAdmin-Rolle verwenden, wenn deren Rechte für die Aktion, die sie unternehmen müssen, erforderlich sind. Entwickler, die Zugang zu privilegierten Konten haben, sollten nur die mit mehr Rechten ausgestatteten Konten verwenden, wenn sie wirklich eines deren Rechte benötigen, und für ihre reguläre Arbeit ein normales Konto mit weniger Rechten verwenden.
Es mag am Anfang etwas kompliziert scheinen, da Leute aus ihrer „Komfortzone“, alle Befugnisse zu besitzen, herausgezwungen werden, doch nach einer Zeit der Umgewöhnung wird das Ergebnis ein bei weitem sichereres System sein.

Indem man angemessen eingeschränkte Konten anstelle von “root”/”superuser”-Befugnissen während der Entwicklung verwendet, wird ein Entwickler früh auf potentielle Sicherheitsprobleme aufmerksam, und auch versehentliches Löschen oder Ändern bestimmter Objekte wird verhindert.

Was nun eine erfolgreiche Umsetzung in der realen Welt angeht, gibt es noch ein weiteres Prinzip: KISS: Keep it simple, stupid:

 “Realitätscheck”

Wenn die Nutzer-/Rollentrennung bis ins Extreme befolgt wird, ist es wie mit der „6. Normalform“: tolle Vorteile in der Theorie, aber total unpraktisch. Den Nutzer dazu zu bringen, zu einer anderen Rolle zu wechseln, indem er einen zweiten, dritten usw. Login verwendet, um eine Tabelle zu erstellen, während seine reguläre Aufgabe sein mag, Prozedurcode zu ändern, macht meistens keinen Sinn.

Tatsächlich sollten die Fälle, bei denen man wirklich dieses Prinzip “leben” kann, auf die sensibelsten Aufgaben beschränkt sein. Das beste Beispiel ist eine “SecurityDeployment-Role” vs. dem regulären DBA. Das ist maßgeblich für ein System, das zum Beispiel manipulationssicher sein muss.
Ein weiteres gängiges Beispiel ist der Deployment-Prozess von der Entwicklung zum Test/zur Produktion, der nur zu bestimmten Zeiten läuft. Oder in einem Datawarehouse-System der ETL-Prozess: wenn er sicherheitstechnisch richtig umgesetzt wird, wird er nur erfolgreich sein, wenn er über das beabsichtigte Auftrags-/Proxy-Konto läuft, und nicht, wenn ein regulärer Nutzer oder gar Entwickler ihn ausführt, aufgrund der verschiedenen Bereiche, auf die von ihm zugegriffen werden.

Damit kommt eine organisatorische Herausforderung: wie stellt man die Einhaltung seiner Regeln sicher?
Die Antwort dazu findet sich im großen Thema Compliance, das über den Rahmen dieses Artikels hinausgeht, obwohl ich an bestimmten Stellen einige Hinweise geben werde.

Mit all diesem im Hinterkopf werden die folgenden Ideen von mir, die ich hier teile, hoffentlich mehr Sinn ergeben.

Rollenkonzept

Um Sicherheit in einer SQL Server-Umgebung zu kontrollieren, ist die Nutzung von Rollen ein ultimatives Prinzip. SQL Server bietet Serverrollen und Datenbankrollen, die auf jedermanns eigene Bedürfnisse durch Nutzung des umfangreiches Rechtesystems, das mit SQL Server 2005 kam, angepasst werden können.

Wenn ich mit Kunden arbeite, ist einer der ersten Schritte, Prozesse zu identifizieren. Ja richtig, Prozesse, noch keine Rollen. Denn Rollen sind nur ein Mittel, um Prozesse zu ermöglichen und Nutzer ihre Arbeit tun zu lassen. (Offensichtlich kann ein „Prozess“ sowohl ein technischer Nutzer als auch eine logische Definition eines Arbeitsablaufes sein. Wenn nötig, werde ich den Anwendungsfall genauer definieren.)

Über die Jahre, in denen ich in diesem Bereich gearbeitet habe, haben sich einige Rollen herausgestellt, die typischerweise benötigt werden.
Hier sind einige Beispiele, die oft Verwendung finden:

Entwicklung/ “Entwickler

  • Entwickelt die Datenbankobjekte, Analysis Services cubes, Reporting Services Reports, Integration Services Pakete und andere

Deployment

  • Überträgt Releases von einer Umgebung in eine andere

Anwendungs-/Projektsupport, “App-Support”

  • Führt Support für ein Projekt auf einmal durch. Ein Projekt kann eine oder mehrere Anwendungen sein, meistens eine.

Überwachung/“Monitoring”/Betrieb

  • Support auf Serverebene.

ETL-Prozesse

  • Unbeaufsichtigte Routinen für Import & Export von Daten, speziell in Datawarehouse-Systemen.

Auditor

  • Ausschließlich um Audits auf dem gesamten Server durchzuführen. Wird nirgendwo etwas ändern.

Und immer wird es geben:

Datenbankadministrator

  • Hat umfassende Berechtigungen aber keine (täglichen) sicherheitsbezogenen Aufgaben

Systemadministratoren/ “Sysadmins

  • haben volle Berechtigungen auf den Systemen

Endnutzer

  • greifen nur auf die Daten zu über Berichte, Excel oder andere Frontends
Rollenbeispiele, Hindernisse und Hinweise auf Lösungen

Im Folgenden einige Beispiele von Rollen und Hindernissen, die man antreffen wird, wenn man diese sichern möchte.

Monitoring

Wie kann man bestimmte Rollen (d.h. Entwickler) dazu ermöglichen, Performance-Daten aus der Produktions- oder Testumgebung zu erhalten, ohne exzessive Berechtigungen zu vergeben? Für Extended Event Sessions hat man das ALTER TRACE, aber das ermöglicht Zugriff auf Daten, die sensibel sein könnten. Und was ist mit Performance Monitor, der auf Windowsebene ist? Dort gibt es 2 mögliche Rollen: Performance Monitor Users und Performance Log Users.

Eine mögliche Lösung, die ich erfolgreich umgesetzt habe, ist, eine Anzahl von PerfMon Datensammlungssätzen mit Leistungsindikatoren und Extended Event Traces vorbereitet zu haben, um sie mit speziellen Aufträgen zu starten. Zugriff auf die Ergebnisdateien muss auf Windows-Dateifreigabeebene implementiert werden.
Apropos Dateien: vergesst nicht Ausgabedateien von SQL Agent Aufträgen, die wertvolle Informationen für Troubleshooting enthalten könnten.

Um Serverstatusdaten, basierend auf den gängig verwendeten DMVs (sys.dm_exec_requests, sys.dm_exec_query_stats, sys.dm_os_memory_clerks und viele mehr), anzusehen, besteht die Notwendigkeit, diese nach der jeweiligen Datenbank des Projektes zu filtern. Um das zu erreichen, kann man ein spezielles Set an gespeicherten Prozeduren implementieren, die natürlich korrekt mit einem Zertifikat signiert werden müssen, um auf Daten außerhalb des aktuellen Datenbankbereichs zuzugreifen und einen Pfad für Privilegienerweiterung/privilege elevation zu verhindern. Das Ergebnis kann auch in einer benutzerdefinierten Datenbank gespeichert werden. Nach Sarpedon Quality Lab Methodik liegen Code und Daten für diese letztlich in verschiedenen Datenbanken: SQL_Analysis_Code, SQL_Analysis_Data.

Eine Alternative kann die Verwendung von Drittanbieter-Monitoringsoftware mit eingebautem Rollenkonzept sein, wie es ein professionelles Werkzeug, wie es SQLSentry® anbietet.

SQL Agent Aufträge

Jeder SQL Server enthält Aufträge für Wartung, aber auch sehr häufig für zeitgesteuerte Prozesse in Verbindung mit einer Anwendung. Das können ETL (Import, Export) oder andere Batch-Prozesse sein.

Eine Sache ist es, diese Aufträge vom Entwicklungsserver zur Produktion zu übertragen, was im nächsten Abschnitt behandelt wird; eine andere Sache ist es, wer erhält Berechtigungen, diese manuell zu starten, die Historie für Troubleshooting-Zwecke oder anderes zu prüfen und vielleicht, wenn nötig, sie zu ändern. Das eingebaute Sicherheitssystem für SQL Server Agent ist sehr eingeschränkt und nicht wirklich flexibel. Zum Beispiel:

  • ein Auftrag kann genau einen Besitzer haben (kann kein Windowsgruppenlogin/-rolle sein, obwohl eine Gruppe Berechtigungen haben kann)
  • man kann entweder die gesamte Historie lesen oder die Historie von Aufträgen, die man besitzt (noch einmal: aber nur ein einzelner Login kann einen Auftrag besitzen)
  • man kann entweder alle Aufträge starten oder die, die man besitzt.

Hier ist wieder ein Fall, wo ein benutzerdefiniertes Sicherheits-Framework notwendig ist, dass einiges an Coding erfordert, um mehr Freiheit zu ermöglichen in Sachen wer was tun kann.

Deployment

Das Problem mit dem Deployment-Prozess ist nicht ein “CREATE TABLE/PROCEDURE” etc. Diese Berechtigungen können leicht auf Datenbankebene gegeben werden. Es wird komplizierter in Fällen von Multi-Tenant-Datenbanken, aber Fälle von verschiedenen Berechtigungen auf verschiedene Schemas sind sicher die absolute Ausnahme. Aus meiner Erfahrung ist die Verwendung von Schemas als Sicherheitsgrenze selbst immer noch selten (mehr dazu hier: Schema-Design für SQL Server: Empfehlungen für Schema-Design mit Sicherheit im Blick ). Eine Kombination aus Datenbankebenen-Berechtigungen und Schema-Ebenen-Berechtigungen verwenden zu müssen, hilft sicherlich nicht, aber das ist ein eher kleines Problem.

Die wahren Probleme treten auf, wenn Entwickler Logins, Datenbanken und andere Serverebenen-Objekte erstellen, insbesondere sicherheitsbezogene. Man kann die notwendigen Berechtigungen wie ALTER ANY LOGIN, ALTER ANY SERVER ROLE und CREATE SERVER ROLE der Deployment-Rolle geben, aber man wird einen organisatorischen Prozess benötigen, um sicherzustellen, dass nur validierte Kommandos dieser Art auf dem Produktionsserver ausgeführt werden, und niemand einen „Hintertür-Admin“ innerhalb eines riesigen ALTER TABLE-Scripts versteckt.

Auf Datenbankebene ist die db_owner-Mitgliedschaft notwendig, um Rollenmitgliedschaften für eingebaute Rollen (wie db_datareader) zu bearbeiten. Das mag aber nicht akzeptabel sein für die jeweilig benötigte Sicherheitsstufe. Wenn eine Anwendung custom, benutzerdefinierte Rollen verwendet, kann die Mitgliedschaft in den Rollen db_accessadmin und db_securityadmin (um Berechtigungen zu vergeben) verwendet werden. Dem erfahrenen Sicherheitsspezialisten wird auffallen, dass dies jedoch ein Risiko für Privilegienerweiterung enthält. Also kann man wieder nicht blind den Berechtigungen vertrauen und benötigt daher einen benutzerdefinierten Prozess um das herum.

Nun noch eine Sache zu SQL Agent Aufträgen in msdb: Es muss einem klar sein, dass zur Deployment/Erstellungszeit, Aufträge dem jeweiligen Ersteller gehören. Aber meistens möchte man, dass Aufträge von einer anderen Rolle (wie eine echte Person, die eine „Support“-Rolle hat) gestartet werden können.
Das bedeutet, dass der Besitzer nach der Erstellung geändert werden muss. Schritte mit Zugriff auf Subsysteme wie CMD müssen darauf eingestellt werden, ein passendes Proxy-Konto zu verwenden.
Und wer wird Berechtigungen haben, das zu tun? Um diese Routine wiederum zu sichern, kann man signierte gespeicherte Prozeduren verwenden, um Manipulationen zu verhindern.

Mittlerweile wird der ausdauernde Leser festgestellt haben, dass das wahrhaftige Sichern eines Systems echte Arbeit ist… 😉

Maintenance

Wartung bedeutet natürlich viel Energie für ein System. Man kann nicht mit weniger als sysadmin dafür davonkommen, es sei denn, man geht die Extra-Meile, um für jede Datenbank Berechtigungen zu vergeben. D.h. man benötigt ALTER TABLE für REBUILD/REGORGANIZE von Indexen (und ALTER ANY CONNECTION für die “ABORT_AFTER_WAIT = BLOCKERS” -Option) und UPDATE STATISTICS. Für DBCC CHECKDB ist jedoch db_owner das Minimum. Dann wird man über das Aufräumen in Systemtabellen und Ausgangsdateien auf OS-Ebenen nachdenken und zum Schluss kommen, dass es meistens akzeptabel ist, sysadmin über SQL Agent zu verwenden.

Datenbankadministrator

Um Datenbankadministratoren zu kontrollieren, muss eine strikte Trennung von „Sicherheitsadministratoren“ befolgt werden. Leider kann das CONTROL SERVER Kommando zum Zeitpunkt dieses Artikels nicht als völlig sicher betrachtet werden (SQL Server 2017).

In SQL Azure Database ist das Konzept etwas anders. Ein dbmanager zum Beispiel muss nicht unbedingt alle Datenbanken besitzen. Um Logins zu erstellen, gibt es die loginmanager-Rolle, die separat vergeben werden kann.

Es kann auch notwendig sein, den Inhalt bestimmter sensibler Tabellen in der Datenbank zu verschlüsseln. Zu diesem Zweck hat Always Encrypted die Fähigkeit, den Entschlüsselungsschlüssel komplett außerhalb des SQL Servers zu behalten und ist ein gutes Beispiel für die Trennung zwischen denen, die die Daten besitzen (und sie lesen können) und denen, die die Daten verwalten (aber sie nicht lesen können sollten).

Hotfixing

Ob nun “Hotfixing” als ein valider Anwendungsfall betrachtet werden kann, hängt von der Striktheit der jeweiligen Entwicklungs-Lifecycles ab. Ich habe festgestellt, dass diese Ausnahme nützlich ist.

Die Herausforderung hierbei ist es, sehr sensible Berechtigungen mit 2 Konditionen zu vergeben:

  • nur bei Freigabe durch einen Vorgesetzten
  • nur für einen begrenzten Zeitraum.

Das ist ein netter Anwendungsfall für ein zeitbasiertes Berechtigungssystem, das mit nutzerdefiniertem Code in SQL Server umgesetzt werden kann.

Außerdem ist Auditing hier äußerst wichtig aufgrund der hohen Berechtigungen, die beteiligt sind. – Auditing ist ein eingebautes Feature von SQL Server und basiert auf der Infrastruktur der Extended Events (Erweiterte Ereignisse). Tatsächlich muss man für bestimmte Fälle zusätzlich Extended Events verwenden.

Auditing

Wenn man Sicherheit Ernst nimmt – und wenn ihr bis hierhin gelesen habt, stehen die Chancen sehr gut – muss man unbedingt alle sicherheitsrelevanten Aktivitäten wie das Ändern von Rollenmitgliedschaften, Berechtigungen auditieren.
Und vergesst auch nicht, jegliche Änderungen am Audit (Audit-Traces) zu auditieren. Ein einfaches “AUDIT SESSION CHANGED” reicht für eure Sicherheitseinstufung vielleicht nicht aus 🙂

Schlussbemerkungen

Dies waren einige Beispiele von Rollen aus dem echten Leben, die ich für Kunden umsetze, die eine (fast) kugelsichere Separation of Duties benötigen. Natürlich gibt es noch mehr Rollen zu betrachten.
Während SQL Server den Titel der sichersten Datenbank tatsächlich seit mehreren Jahren bereits verdient hat (nach Anzahl der Sicherheitslücken), sind Attacken aus dem Inneren sehr gegenwärtig und stellen eine konstante Gefahr für jedes System dar. Um sich davor zu schützen, reicht die reine Abwesenheit von sicherheitsrelevanten Bugs bei weitem nicht aus, wenn es keine Grenzen gibt oder nur schwache Grenzen umgesetzt wurden. Das kann das gemeinsam genutzte sa-Konto sein („jeder Tag ist ein Notfalltag“), andere hochprivilegierten Kontos, oder die reine Möglichkeit, Daten in der Produktion zu ändern, wenn ein Update läuft.

Einige Bemerkungen zu Reporting Services und Analysis:

Reporting Services erlauben auch die Definition von benutzerdefinierten Rollen, aber das Konzept ist ganz anders als das vom SQL Server, wo ein Nutzer durch die gesamte Datenbank hinweg ein Mitglied der Rolle ist: in SSRS erfüllt ein Nutzer eine bestimmte Rolle auf einer spezifizierten Ebene in der (Ordner-)Hierarchie und eine andere Rolle auf einer anderen. Eine sehr interessante Herangehensweise, die aufgrund der strikt hierarchischen Struktur und der fast trivialen Berechtigungen, verglichen mit der eines komplexen RDBMS wie SQL Server, einfach zu verfolgen ist.

Analysis Services kennt nutzerdefinierte Datenbankebenen nur mit noch weniger Berechtigungen, die sich nur schwer vollständig sichern lassen, besonders dann, wenn es um bestimmte administrative Aufgaben geht. Wenn es um den Endnutzer geht, kann eine Art label-basierte Sicherheit auf Hierarchie-/Zellebene umgesetzt werden.

Es gibt einige offizielle Whitepapers zu SoD in SQL Server, die ich absolut als technischen Hintergrund zu diesem Thema empfehle:

Ich empfehle auch Erland Sommarskogs Artikel zu Packaging Permissions in Stored Procedures, was eine wesentliche Technik ist, die für fast alle der dargestellten Lösungen verwendet werden kann.

Wunschliste ans Sicherheitsteam

Ich würde gern mit einer Wunschliste an das Datenbank-Sicherheitsteam in Redmond und Israel abschließen.

1) Da es gefährlich sein kann, bestimmte Rollen zu kombinieren, und es keine Möglichkeit gibt, versehentliches Vergeben von speziellen Rollen zu verhindern, ist das einzige, was man tun kann, regelmäßige Checks durchzuführen. Dafür können Richtlinien-basierte Verwaltung (PBM) mit ExecuteSQL-Ausdrücken oder reine SQL-Aufträge zeitgesteuert werden. Ich würde mir eine Art Anti-Affinität und “exception-bit” Technik für (hauptsächlich Server-)Rollen wünschen.

2) Msdb lässt sich wirklich schwer handhaben. Erstens kann es für Privilegienerweiterungsattacken verwendet werden, und zweitens ist das ganze Besitzertum/Berechtigungsset für Aufträge viel zu begrenzt. Ein hierarchisches System für Aufträge (ähnlich wie SSRS und etwas ähnlich wie SSISDB) mit Berechtigungen auf bestimmten Ebenen wären toll.
Für viele Anwendungsfälle wäre es sicherlich toll, Aufträge zu haben, die innerhalb einer Nutzerdatenbank stecken. Vielleicht ist die Lösung, bestimmte Aufträge innerhalb einer Nutzer-Datenbank zu haben, und andere innerhalb ihrer eigenen Datenbank (aber nicht msdb). Ich verstehen jedoch, dass dies sehr complex ist. Denn irgendwie muss SQL Agent auf jede Datenbank zugreifen und Aufträge für sie prüfen. Teil eins wäre schon toll.

3) Extended Events auf Datenbankebene. Das sollte schon fast segelfertig sein, wenn ich mir die SQL Azure Database so ansehe 🙂

4) Ein “originating database” bit in DMVs für automatisches Filtern – ähnlich wie Systemtabellen und Berechtigungen funktionieren.

5) Die Arbeit zur Abkoppelung bestimmter Systemprozesse/DBCC Kommandos vom sysadmin-bit beenden. Es wurde bereits viel in diesem Bereich getan, so dass ich zuversichtlich bin, dass es früher oder später fertig wird.

6) Im Allgemeinen würde ich gern mehr eingebaute Rollen haben, aber wichtiger noch ist die Möglichkeit, „genau die Berechtigungen, die benötigt werden“, zu erstellen. Also plädiere ich für “mehr Möglichkeiten”, um die obengenannten Wünsche zu ermöglichen.

Andreas Wolter, Sarpedon Quality Lab

Tags:

Categories: Security

0 Kommentare

Dein Kommentar

An Diskussion beteiligen?
Hinterlasse uns Deinen Kommentar!

Schreibe einen Kommentar

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