Hoe kan een CLR-assembly die is gemaakt met PERMISSION_SET =SAFE toegang krijgen tot externe systeembronnen, onbeheerde code oproepen en sysadmin-rechten verwerven?
Dit komt door beveiligingswijzigingen die zijn aangebracht in het .NET Framework, beginnend in versie 4.5 (denk ik).
MSDN-documentatie voor Code Access Security Basics stelt:
Het .NET Framework biedt een mechanisme voor het afdwingen van verschillende niveaus van vertrouwen op verschillende code die wordt uitgevoerd in dezelfde applicatie, Code Access Security (CAS) genaamd. Code Access Security in .NET Framework mag niet worden gebruikt als een mechanisme voor het afdwingen van beveiligingsgrenzen op basis van code-oorsprong of andere identiteitsaspecten. We werken onze richtlijnen bij om weer te geven dat Code Access Security en Security-Transparent Code niet worden ondersteund als beveiligingsgrens met gedeeltelijk vertrouwde code, met name code van onbekende oorsprong. We raden af om code van onbekende oorsprong te laden en uit te voeren zonder alternatieve veiligheidsmaatregelen te nemen.
En verwijst vervolgens naar de pagina voor beveiligingswijzigingen in het .NET Framework waarin staat:
De belangrijkste verandering in beveiliging in .NET Framework 4.5 zit in sterke naamgeving.
Wat vervolgens verwijst naar de documentatie voor Enhanced Strong Naming waarin staat:
Sterke naamsleutels bestaan uit een handtekeningsleutel en een identiteitssleutel. Het samenstel is ondertekend met de handtekeningsleutel en wordt geïdentificeerd door de identiteitssleutel. Vóór .NET Framework 4.5 waren deze twee sleutels identiek. Vanaf .NET Framework 4.5 blijft de identiteitssleutel hetzelfde als in eerdere .NET Framework-versies, maar de handtekeningsleutel is verbeterd met een sterker hash-algoritme. Bovendien wordt de handtekeningsleutel ondertekend met de identiteitssleutel om een tegenhandtekening te maken.
OOK vermeldt de documentatie voor Secure Coding Guidelines:
Code Access Security en Security-Transparante code worden niet ondersteund als beveiligingsgrens met gedeeltelijk vertrouwde code. We raden af om code van onbekende oorsprong te laden en uit te voeren zonder alternatieve veiligheidsmaatregelen te nemen...
Het beveiligingsmodel voor .NET is dus jaren geleden gewijzigd, maar SQL Server (tot SQL Server 2017) mag het oude beveiligingsmodel blijven gebruiken. Het lijkt erop dat vanaf SQL Server 2017 de beslissing is genomen om het oude beveiligingsmodel niet langer te ondersteunen.
Ik vermoed dat het toestaan van het oude beveiligingsmodel was:
-
voorkomen dat SQL Server (tenminste de CLR-gerelateerde functionaliteit/componenten) gebaseerd is op de nieuwere .NET Framework-versies, en
-
verantwoordelijk voor de abrupte verwijdering van SQLCLR als ondersteunde functie van Azure SQL Database (ondersteuning was eind 2014 toegevoegd met de lancering van v12, maar werd vervolgens volledig verwijderd op 15 april 2016).
Dus, ja, dit is nogal balen. Wat het betekent (althans voorlopig) is dat men eerst . moet maak een Certificaat of Asymmetrische Sleutel (die is gebruikt om eventuele Assemblies te ondertekenen die moeten worden geladen) in [master]
om vervolgens een Login aan te maken van en vervolgens UNSAFE ASSEMBLY
. toe te kennen naar die login. Dit is dezelfde reeks gebeurtenissen die men moet doen bij het laden van EXTERNAL_ACCESS
en UNSAFE
Assemblages, maar nu, helaas, moet worden gedaan voor zelfs SAFE
Samenstellingen.
Er is momenteel geen mechanisme om dit op een volledig draagbare manier af te handelen (d.w.z. niet te vertrouwen op externe bestanden) en kan niet worden afgehandeld door Visual Studio / SSDT zonder handmatige tussenkomst. Dit was min of meer het geval, maar het was in ieder geval mogelijk om een set-up te maken om dit op een volledig draagbare manier af te handelen (d.w.z. volledig opgenomen in een .sql-script):zie Stairway to SQLCLR Level 7:Development and Security voor details (dit is een artikel dat ik heb geschreven).
Het is mogelijk om een certificaat te maken van hex bytes (d.w.z. FROM BINARY = 0x...
) maar dat werkt niet met Visual Studio (die afhankelijk is van MSBuild) / SSDT, aangezien het gebruik van het certificaat het gebruik van signtool
vereist en MSBuild gebruikt sn
.
Om dit werkbaar te maken zodat het publicatieproces van Visual Studio / MSBuild / SSDT werkt (wat op zijn beurt zou betekenen dat iedereen een volledig op zichzelf staand .sql-script zou kunnen maken dat in staat is om de asymmetrische sleutel te maken zonder afhankelijk te zijn van een extern bestand), de CREATE ASYMMETRIC KEY
opdracht moet worden verbeterd om te kunnen worden gemaakt op basis van een binaire tekenreeks. Ik heb deze suggestie gedaan op Microsoft Connect - Sta toe dat asymmetrische sleutel wordt gemaakt op basis van binaire hex-bytes-tekenreeksen, net als CREATE CERTIFICATE - dus ondersteun het alstublieft :-).
Als alternatief (voorlopig, totdat MS hopelijk een betere methode creëert, zoals mijn asymmetrische sleutelsuggesties), kun je een van de twee technieken proberen die ik in de volgende blogposts beschrijf (beide werken volledig met SSDT):
- SQLCLR vs. SQL Server 2017, deel 2:“CLR strikte beveiliging” – Oplossing 1
- SQLCLR vs. SQL Server 2017, deel 3:"CLR strikte beveiliging" - Oplossing 2
Als laatste resort, kunt u de volgende aanpak overwegen:
-
TIJDELIJK stel de
[master]
in Database naarTRUSTWORTHY ON
Voor de volgende stap (d.w.z.
CREATE ASSEMBLY
) om succesvol uit te voeren, de Login die de database-eigenaar is (d.w.z. dezelfde SID die wordt gebruikt door de[dbo]
Gebruiker van[master]
) moet deUNSAFE ASSEMBLY
. hebben toestemming. Als[master]
is eigendom vansa
of een andere systeembeheerder, dan heeft het alle rechten en is aan deze vereiste voldaan. Maar als[master]
eigendom is van een laaggeprivilegieerde login (een "best practice"), dan moet u de volgende instructie uitvoeren om deCREATE ASSEMBLY
om te werken wanneerTRUSTWORTHY
isON
:EXEC (N'USE [master]; GRANT UNSAFE ASSEMBLY TO [{DB_Owner_Login}];');
- Maak de assembly in
[master]
- Maak de asymmetrische sleutel van de vergadering
- Laat de vergadering vallen
- stel de
[master]
in Database naarTRUSTWORTHY OFF
- Maak de login aan met de asymmetrische sleutel
- Grant
UNSAFE ASSEMBLY
naar die Login (dit vervangt de noodzaak voor de DB waar de Assembly wordt geladen om te worden ingesteld opTRUSTWORTHY ON
en voor de eigenaar Log in om deUNSAFE ASSEMBLY
. te hebben toestemming).
Let op:ik heb niet voeg hier de nieuwe functie "Trusted Assembly" als optie toe. De reden dat het niet werd genoemd, is omdat het veel meer gebreken dan voordelen heeft, om nog maar te zwijgen van het feit dat het in de eerste plaats helemaal niet nodig is, aangezien de bestaande functionaliteit al de situatie afhandelde die "Trusted Assemblies" moest aanpakken. Voor volledige details hierover en een demo van de juiste manier om met bestaande, niet-ondertekende Assemblies om te gaan, zie:SQLCLR vs. SQL Server 2017, Part 4:“Trusted Assemblies” – The Disappointment.