|
Possibilities
So what are the general variations of database ownership? Let me start with the most common and actually WORST possibilities (Yes, I mean it exactly as I say ;-) ):
- SA-Account
- Some other SQL-Account with sysadmin privileges
- Windows Login with sysadmin privileges
A first improvement(? – really?):
4. Any of the above with Status = Disabled
And then:
5. A ”shared” account without any special server role or permissions (aka “1 Account per Server”)
6. 1 Account per Database
7. 1 Account per Application
8. 1 Account per Group of databases
+ all of them not only Disabled but with a Denied Connect-Permission
|
Möglichkeiten
Was sind also die allgemeinen Variationen von Datenbanken-Besitztum?
Fangen wir mit den häufigsten und eigentlich SCHLECHTESTEN Möglichkeiten an (Ja, das meine ich genau so, wie es hier steht ;-) ):
- SA-Konto
- Irgendein anderes SQL-Konto mit sysadmin-Privilegien
- Windows Login mit sysadmin-Privilegien
Eine erste Verbesserung(? – wirklich?):
4. Alle der oben angegebenen mit Status = Deaktiviert
Und dann:
5. Ein „geteiltes“ Konto ohne eine spezielle Serverrolle oder Rechte (Alias „1 Konto pro Server“)
6. 1 Konto pro Datenbank
7. 1 Konto pro Anwendung
8. 1 Konto pro Datenbank-Gruppe
+ alle davon nicht nur Deaktiviert sondern mit einer verweigerten Verbindungs-Berechtigung
|
|
My Recommendation:
Depending on your environment: Any of 5, 6, 7 or 8:
Create a specific Login without any extra permissions + Deny Connect.
The most simple approach and yet better than sa is: one database owner per server. Example for (5):
- Database1 owned by DBOwner
- Database2 owned by DBOwner
- Database3 owned by DBOwner
Simple and self-explanatory.
The other extreme and most secure is: per database. Example for (6):
- Database1 owned by DBOwner_Database1
- Database2 owned by DBOwner_Database2
- Database3 owned by DBOwner_Database3
- Database4 owned by DBOwner_Database4
Some applications use a number of different databases. For them it’s perfectly fine to use the same database owner account. So create an account per application.
Example for (7):
- App1Database1 owned by DBOwner_App1
- App1Database2 owned by DBOwner_App1
- App2Database1 owned by DBOwner_App2
- App2Database owned by DBOwner_App2
Another approach is kind of a compromise between 1 Database-Owner Account per Server and One per database: Define the level of security needed per database. Then create a dedicated account for the most critical Databases. And for the others use a shared owner/account, possibly divided in 2 or more groups.
Example for (8):
- CriticalDatabase1 owned by DBOwner_Level1Dedicated1
- CriticalDatabase2 owned by DBOwner_ Level1Dedicated2
- Level2Database1 owned by DBOwner_Level2
- Level2Database2 owned by DBOwner_Level2
I hope my samples give you an idea. :-)
So why this effort? Let me put it this way: ”Why not sa?”. First: If you think about it, it actually makes little sense that the highest privileged account in SQL Server is being recommended by so many, even professionals + in Whitepapers (!) – when security is the focus. It is really wrong, as wrong as it could possibly get. I mean, as you can see, there are other options out there. The top reason why SA keeps getting recommended is administration itself: It eases the setup for failover and regular database restores, since SA is always available at any server and hence a broken database owner can be avoided with almost no extra work. But that’s “only” from a perspective of maintenance. With regard to security it is totally on contrary to the Principle of least privilege.
It may not matter a lot, if everything else is tightened, but that’s hardly a thing to rely on especially in bigger environments where things change and many people have access and permissions to. Especially in the context of the trustworthy-setting for a database, this completely opens the system for privilege escalation attacks from inside. It is then a piece of cake to gain system level permissions once you are for example in the db_owner database group – like many applications are, if they are not sysadmin already. - Remember: the owner of a database cannot be denied anything inside and with his database. So he can change structure, create backups, break log-backup-chain and also drop it completely.
And since the attack starts from inside, it really doesn’t matter whether the sa/sysadmin account is disabled as you may now realize.
Having a dedicated account with zero special permissions as database owner prevents database principals from gaining system level permissions as a sysadmin has, even in the case of the database being trustworthy. And trustworthy is one of the dirty little shortcuts for developers implementing CLR code inside the database and avoiding the hassle of having to use certificates under certain conditions. The same is often done for code that needs to get server-level data from inside the database.
|
Meine Empfehlung:
Abhängig von eurer Umgebung: eine von 5, 6, 7 oder 8:
Ein spezifisches Login errichten ohne extra Rechte + Deny Connect.
Die einfachste Herangehensweise und doch besser als sa ist: ein Datenbankbesitzer pro Server.
Beispiel für (5):
- Datenbank1 im Besitz von DBOwner
- Datenbank2 im Besitz von DBOwner
- Datenbank3 im Besitz von DBOwner
Einfach und selbsterklärend.
Das andere Extrem und dabei die sicherste ist: pro Datenbank.
Beispiel für (6):
- Datenbank1 in Besitz von DBOwner_Database1
- Datenbank2 in Besitz von DBOwner_Database2
- Datenbank3 in Besitz von DBOwner_Database3
- Datenbank4 in Besitz von DBOwner_Database4
Einige Anwendungen verwenden eine Reihe von unterschiedlichen Datenbanken. Für sie ist es völlig ausreichend, das gleiche Datenbankbesitzerkonto zu verwenden. Erstellt also ein Konto pro Anwendung.
Beispiel für (7):
- App1Database1 in Besitz von DBOwner_App1
- App1Database2 in Besitz von DBOwner_App1
- App2Database1 in Besitz von DBOwner_App2
- App2Database in Besitz von DBOwner_App2
Eine andere Herangehensweise ist eine Art Kompromiss zwischen 1 Datenbankenbesitzerkonto pro Server und einem pro Datenbank: Definiere das Sicherheitslevel, das je Datenbank gebraucht wird. Dann erstelle ein spezielles Konto für die kritischsten Datenbanken. Und für die anderen Besitzer einen gemeinsamen Besitzer-/Konto verwenden, möglicherweise in 2 oder mehr Gruppen geteilt.
Beispiel für (8):
- CriticalDatabase1 in Besitz von DBOwner_Level1Dedicated1
- CriticalDatabase2 in Besitz von DBOwner_ Level1Dedicated2
- Level2Database1 in Besitz von DBOwner_Level2
- Level2Database2 in Besitz von DBOwner_Level2
Ich hoffe, meine Beispiele geben euch eine Vorstellung. :-)
Aber warum diese Mühe? Lasst es mich so ausdrücken: “Warum nicht sa?” Zuallererst: Denkt man darüber nach, ergibt es eigentlich wenig Sinn, dass das höchstprivilegierte Konto beim SQL Server von so vielen empfohlen wird, selbst von Profis + in Whitepapers (!) – wenn Sicherheit im Fokus steht. Es ist wirklich falsch, so falsch wie es nur irgend sein kann.
Schließlich gibt es da draußen, wie ihr sehen könnt, noch andere Optionen.
Die Grund Nr. 1, warum SA immer wieder empfohlen wird, ist die Administration selbst: Es erleichtert das Einrichten für Failover und regelmäßige Datenbankenwiederherstellungen, da SA immer auf jedem Server verfügbar ist und damit ein kaputter Datenbankbesitzer mit wenig zusätzlichem Aufwand verhindert werden kann. Aber das ist „nur“ aus Sicht der Wartung. Was die Sicherheit angeht, steht es völlig im Gegensatz zum Prinzip des geringsten Privilegs.
Es mag nicht viel ausmachen, wenn alles andere straff sitzt, aber darauf sollte man sich nicht verlassen, besonders in größeren Umgebungen, wo sich Dinge ändern und viele Leute Zugriff und Befugnisse haben.
Besonders im Kontext der Trustworthy-Einstellung für eine Datenbank öffnet dies das System komplett für privilege escalation-Angriffe von innen. Dann ist es ein Kinderspiel, Systemlevel-Befugnisse zu erlangen, wenn man einmal z.B. in der db_owner Datenbankengruppe ist – wie es viele Anwendungen sind, wenn sie nicht bereits sysadmin sind.
Denkt dran: dem Datenbankenbesitzer kann weder innerhalb noch mit seiner Datenbank etwas verweigert werden. Er kann also die Struktur verändern, Backups erstellen, Log-Backup-Chain brechen und sie auch komplett löschen.
Und da der Angriff von innen anfängt, ist es wirklich egal, ob das sa/sysadmin Konto deaktiviert ist, wie ihr jetzt realisiert haben werdet. Ein spezielles Konto mit Null speziellen Befugnissen als Datenbankbesitzer zu haben hindert Datenbank-Prinzipale daran, System-Level-Befugnisse zu erlangen, wie sie ein sysadmin hat, selbst in dem Fall, dass die Datenbank vertrauenswürdig ist. Und „trustworthy“ ist eine der unsauberen kleinen Abkürzungen für Entwickler, die CLR-Code im Innern der Datenbank ausführen und sich dabei die Umstände sparen, unter bestimmten Bedingungen Zertifikate benutzen zu müssen. Dasselbe wird oft für Code gemacht, der Server-Level-Daten aus dem Innern der Datenbank erreichen muss.
|
|
Call for actions:
Check your databases. You can find my script here: Security-Check-Script & Survey: SQL Server Security - Database-Owners, critical Permissions and role membership Now when you start with securing your databases from database-ownership standpoint, you have to make sure that the very account does exist at any sever where this database gets restored/failed over. Usually you will have a technique in place already to synchronize your server-level principals to your other servers. So this is just one or several more of them.
Also make sure you fully understand your environment and possibly application needs before you just change the owner of your databases. You can start by reading through the links at the bottom.
Vote for an improvement in SQL Server: I have created a suggestion as Connect Item which tackles this problem. My idea is having Microsoft include a special “DBOwner” Account at server level by default, which not only pre-exists and has not permissions, but also never compares to another. I think this would make it much easier to get rid of the habit of “sa” everywhere by also making it simple to maintain. Please vote here: Providing a special Server principal for Database Ownership
|
Handlungsaufruf:
Überprüft eure Datenbanken. Ihr könnt meinen Skript hier finden: Sicherheitsprüfungs-Script & Umfrage: SQL Server Datenbankbesitzer, kritische Rechte und Rollenmitgliedschaft
Wenn ihr jetzt anfangt, eure Datenbanken aus der Perspektive von Datenbanken-Besitz zu sichern, müsst ihr dabei sicherstellen, dass dasselbe Konto auf jedem Server existiert, wo diese Datenbank wiederhergestellt/failed over wird. Normalerweise werdet ihr bereits eine Technik haben, wie ihr eure Server-Level-Prinzipale mit euren anderen Servern synchronisiert. Das sind also nur eine oder einige mehr davon.
Stellt außerdem sicher, dass ihr eure Umgebung und möglicherweise Anwendungsbedürfnisse vollständig versteht, bevor ihr den Besitzer eurer Datenbanken einfach ändert. Ihr könnt damit anfangen, indem ihr euch unten aufgelisteten Links durchlest.
Abstimmen für eine Verbesserung im SQL Server: Ich habe einen Vorschlag als Connect Item erstellt, der dieses Problem behandelt. Meine Vorstellung ist es, Microsoft dazu zu bringen, standardmäßig ein spezielles „DBOwner“ Konto auf Server-Level auszuliefern, das nicht nur bereits immer vorab existiert und keine Rechte hat, sondern auch nie mit anderen vergleichbar ist. Ich denke, dass dies es viel einfacher machen würde, die allgegenwärtige Gewohnheit des „sa“ loszuwerden und es gleichzeitig auch einfach Wartbar machen würde. Bitte hier Eure Stimme abgeben: Providing a special Server principal for Database Ownership
|