/*
--------- TEST 3 FOR SQLCLR on SQL Server 2017 (Windows and Linux) ---------
Created By: Solomon Rutzky / Sql Quantum Leap ( https://SqlQuantumLeap.com/ )
Created On: 2017-08-18
Updated On: 2020-01-16 ~ Added note about Login for database owner needing the
UNSAFE ASSEMBLY permission for CREATE ASSEMBLY to work.
Location: https://pastebin.com/mwi5BidL
Related blog post: https://SqlQuantumLeap.com/2017/08/28/sqlclr-vs-sql-server-2017-part-4-trusted-assemblies-the-disappointment/
Description: This script shows a technique for PROPERLY handling SQLCLR Assemblies,
marked as SAFE and not signed, that reside in databases that are upgraded to
SQL Server 2017 or restored into SQL Server 2017 from a previous version,
while both keeping "clr strict security" enabled and "TRUSTWORTHY" disabled.
Prior to SQL Server 2017 it was not necessary to have SAFE Assemblies signed
and have a corresponding signature-based Login with the UNSAFE ASSEMBLY
permission. As of SQL Server 2017 it is necessary, but the new "Trusted
Assemblies" feature is NOT necessary and should not be used. Ever.
The trick is to simply use module signing, which isn't really a trick at all.
For a detailed, step-by-step explanation, please see the relatd blog post
noted above.
*/
USE [master];
SET NOCOUNT ON;
GO
IF (DB_ID(N'SQLCLRvsClrStrictSecurity') IS NULL)
BEGIN
PRINT 'Creating Database...';
CREATE DATABASE [SQLCLRvsClrStrictSecurity]
COLLATE Latin1_General_100_CI_AS;
END;
IF (DB_ID(N'SQLCLRvsClrStrictSecurity') IS NOT NULL)
BEGIN
PRINT 'Altering Database (make sure RECOVERY=SIMPLE and TRUSTWORTHY=OFF)...';
ALTER DATABASE [SQLCLRvsClrStrictSecurity]
SET RECOVERY SIMPLE,
TRUSTWORTHY OFF;
END;
PRINT 'Making sure that SQLCLR is enabled...';
IF (EXISTS(
SELECT *
FROM sys.configurations sc
WHERE sc.[configuration_id] = 1562 -- "clr enabled"
AND sc.[value_in_use] = 0
))
BEGIN
PRINT 'Enabling SQLCLR...';
EXEC sp_configure N'clr enabled', 1; RECONFIGURE;
END;
PRINT 'Making sure that SQLCLR "strict security" is enabled...';
IF (EXISTS(
SELECT *
FROM sys.configurations sc
WHERE sc.[configuration_id] = 518 -- "show advanced options"
AND sc.[value_in_use] = 0
))
BEGIN
PRINT ' Showing advanced options...';
EXEC sp_configure N'show advanced options', 1; RECONFIGURE;
END;
IF (EXISTS(
SELECT *
FROM sys.configurations sc
WHERE sc.[configuration_id] = 1587 -- "clr strict security"
AND sc.[value_in_use] = 0
))
BEGIN
PRINT ' Enabling CLR strict security...';
EXEC sp_configure N'clr strict security', 1; RECONFIGURE;
END;
-- Verify that "clr strict security" is 1 (i.e. ON), and that TRUSTWORTHY is 0 (i.e. OFF):
PRINT CHAR(13) + CHAR(10) + 'Verifying settings...';
SELECT *
FROM sys.configurations sc
WHERE sc.[configuration_id] = 1587 -- "clr strict security"
SELECT [name], [is_trustworthy_on], [collation_name]
FROM sys.databases WHERE [database_id] = DB_ID(N'SQLCLRvsClrStrictSecurity');
GO
USE [SQLCLRvsClrStrictSecurity];
IF (OBJECT_ID(N'dbo.Date_Format') IS NULL)
BEGIN
PRINT CHAR(13) + CHAR(10) + 'SQLCLR UDF [Date_Format] does not exist:';
PRINT ' TEMPORARILY Altering Database to set TRUSTWORTHY=ON...';
ALTER DATABASE [SQLCLRvsClrStrictSecurity]
SET TRUSTWORTHY ON;
-------------------------------------------------------------------------
-- PLEASE NOTE:
-- For the following CREATE ASSEMBLY statement to execute successfully,
-- the Login that is the database owner (i.e. same SID used by the [dbo]
-- User) needs to have the UNSAFE ASSEMBLY permission. If you just
-- created this database then the database owner is your Login. And, if
-- you are a sysadmin, then you have all permissions and this requirement
-- has been satisfied. But, if you change the owner of the database to
-- be a low-privileged login (a "best practice"), then you will need to
-- execute the following statement in order for CREATE ASSEMBLY to work
-- when TRUSTWORTHY is ON:
--
-- EXEC (N'USE [master]; GRANT UNSAFE ASSEMBLY TO [{DB_Owner_Login}];');
-------------------------------------------------------------------------
IF (ASSEMBLYPROPERTY(N'SQL2017_TrustedAssemblies', N'MvID') IS NULL)
BEGIN
PRINT ' Creating [SQL2017_TrustedAssemblies] Assembly...';
CREATE ASSEMBLY [SQL2017_TrustedAssemblies]
AUTHORIZATION [dbo]
FROM 0x\
4D5A90000300000004000000FFFF0000B80000000000000040000000000000000000000000000000\
0000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD215468\
69732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A\
2400000000000000504500004C010300A4AD9F590000000000000000E00002210B010B00000A0000\
0008000000000000DE28000000200000004000000000001000200000000200000400000000000000\
06000000000000000080000000020000000000000300608500001000001000000000100000100000\
000000001000000000000000000000008C2800004F00000000400000080500000000000000000000\
0000000000000000006000000C000000542700001C00000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000200000080000000000000000000000\
082000004800000000000000000000002E74657874000000E408000000200000000A000000020000\
000000000000000000000000200000602E72737263000000080500000040000000060000000C0000\
000000000000000000000000400000402E72656C6F6300000C000000006000000002000000120000\
0000000000000000000000004000004200000000000000000000000000000000C028000000000000\
480000000200050080200000D4060000010000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000133002001C000000\
010000110F00280F00000A0A12000F01281000000A281100000A731200000A2A1E02281300000A2A\
42534A4201000100000000000C00000076342E302E33303331390000000005006C000000FC010000\
237E000068020000C802000023537472696E67730000000030050000080000002355530038050000\
100000002347554944000000480500008C01000023426C6F62000000000000000200000147150200\
0900000000FA2533001600000100000013000000020000000200000002000000130000000C000000\
01000000010000000200000000000A000100000000000600480041000A0070005B000A007A005B00\
0600C400B2000600DB00B2000600F800B20006001701B20006003001B20006004901B20006006401\
B20006007F01B20006009801B2000600B101B2000600E101CE013B00F50100000600240204020600\
440204020A0097027C020600AC024100000000000100000000000100010001001000280000000500\
01000100502000000000960086000A00010078200000000086189200130003000000010098000000\
0200A500210092001700290092001700310092001700390092001700410092001700490092001700\
510092001700590092001700610092001700690092001700710092001C0081009200220089009200\
13009100920013001900B5023F001100B50244009900BF0248001100920017000900920013002000\
730027002E002B00DD002E00130071002E001B00C1002E002300C7002E000B0052002E0033000901\
2E003B00C1002E00530045012E005B0058012E00630061012E006B006A014D0004800000E1070800\
14000100000000000000620200000400000000000000000000000100380000000000040000000000\
00000000000001004F00000000000000003C4D6F64756C653E0053514C323031375F547275737465\
64417373656D626C6965732E646C6C0053514C32303137767353514C434C52006D73636F726C6962\
0053797374656D004F626A6563740053797374656D2E446174610053797374656D2E446174612E53\
716C54797065730053716C537472696E670053716C4461746554696D6500446174655F466F726D61\
74002E63746F720044617465546F466F726D617400466F726D6174537472696E670053797374656D\
2E5265666C656374696F6E00417373656D626C795469746C6541747472696275746500417373656D\
626C794465736372697074696F6E41747472696275746500417373656D626C79436F6E6669677572\
6174696F6E41747472696275746500417373656D626C79436F6D70616E7941747472696275746500\
417373656D626C7950726F6475637441747472696275746500417373656D626C79436F7079726967\
687441747472696275746500417373656D626C7954726164656D61726B4174747269627574650041\
7373656D626C7943756C7475726541747472696275746500417373656D626C7956657273696F6E41\
747472696275746500417373656D626C7946696C6556657273696F6E417474726962757465005379\
7374656D2E446961676E6F73746963730044656275676761626C6541747472696275746500446562\
756767696E674D6F6465730053797374656D2E52756E74696D652E436F6D70696C65725365727669\
63657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74\
696D65436F6D7061746962696C6974794174747269627574650053514C323031375F547275737465\
64417373656D626C696573004D6963726F736F66742E53716C5365727665722E5365727665720053\
716C46756E6374696F6E417474726962757465004461746554696D65006765745F56616C75650054\
6F537472696E670000032000000000007A9C698E8B40FA4D93155AD83B1E444E0008B77A5C561934\
E0890800021109110D110903200001042001010E05200101113D0420010108170100010054020F49\
7344657465726D696E697374696301042000114D0320000E0420010E0E040701114D1E0100195351\
4C323031375F54727573746564417373656D626C69657300004F01004A68747470733A2F2F53716C\
5175616E74756D4C6561702E636F6D2F63617465676F72792F70726F6772616D6D696E672F73716C\
636C722D76732D73716C2D7365727665722D323031372F00000501000000001501001053716C2051\
75616E74756D204C65617000002B01002653514C20536572766572203230313720767320434C5220\
73747269637420736563757269747900003B010036436F7079726967687420286329203230313720\
536F6C6F6D6F6E2052757A6B792E20416C6C207269676874732072657365727665642E0000120100\
0D323031372E382E32302E30303200000801000200000000000801000800000000001E0100010054\
0216577261704E6F6E457863657074696F6E5468726F77730100000000000000A4AD9F5900000000\
020000001C01000070270000700900005253445313CF1DF386A59840A3A3BFB3702BDE7401000000\
633A5C53514C5175616E74756D4C6561705C50726F6A656374735C426C6F67546F706963735C3231\
33305C53514C323031375F54727573746564417373656D626C6965735C53514C323031375F547275\
73746564417373656D626C6965735C6F626A5C52656C656173655C53514C323031375F5472757374\
6564417373656D626C6965732E706462000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000B42800000000000000000000CE28000000200000\
0000000000000000000000000000000000000000C0280000000000000000000000005F436F72446C\
6C4D61696E006D73636F7265652E646C6C0000000000FF2500200010000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000001001000000018000080000000000000000000000000000001000100000030000080\
00000000000000000000000000000100000000004800000058400000AC0400000000000000000000\
AC0434000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000\
BD04EFFE000001000800E107020014000800E107020014003F000000000000000400000002000000\
000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00\
000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004\
0C040000010053007400720069006E006700460069006C00650049006E0066006F000000E8030000\
0100300030003000300030003400620030000000B0004B00010043006F006D006D0065006E007400\
73000000680074007400700073003A002F002F00530071006C005100750061006E00740075006D00\
4C006500610070002E0063006F006D002F00630061007400650067006F00720079002F0070007200\
6F006700720061006D006D0069006E0067002F00730071006C0063006C0072002D00760073002D00\
730071006C002D007300650072007600650072002D0032003000310037002F000000000044001100\
010043006F006D00700061006E0079004E0061006D00650000000000530071006C00200051007500\
61006E00740075006D0020004C00650061007000000000005C001A000100460069006C0065004400\
650073006300720069007000740069006F006E0000000000530051004C0032003000310037005F00\
540072007500730074006500640041007300730065006D0062006C0069006500730000003C000E00\
0100460069006C006500560065007200730069006F006E000000000032003000310037002E003800\
2E00320030002E0030003000320000005C001E00010049006E007400650072006E0061006C004E00\
61006D0065000000530051004C0032003000310037005F0054007200750073007400650064004100\
7300730065006D0062006C006900650073002E0064006C006C0000009400370001004C0065006700\
61006C0043006F007000790072006900670068007400000043006F00700079007200690067006800\
7400200028006300290020003200300031003700200053006F006C006F006D006F006E0020005200\
75007A006B0079002E00200041006C006C0020007200690067006800740073002000720065007300\
650072007600650064002E000000000064001E0001004F0072006900670069006E0061006C004600\
69006C0065006E0061006D0065000000530051004C0032003000310037005F005400720075007300\
74006500640041007300730065006D0062006C006900650073002E0064006C006C00000070002700\
0100500072006F0064007500630074004E0061006D00650000000000530051004C00200053006500\
720076006500720020003200300031003700200076007300200043004C0052002000730074007200\
6900630074002000730065006300750072006900740079000000000040000E000100500072006F00\
6400750063007400560065007200730069006F006E00000032003000310037002E0038002E003200\
30002E00300030003200000040000C00010041007300730065006D0062006C007900200056006500\
7200730069006F006E00000032003000310037002E0038002E00320030002E003100000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000002000000C000000E03800000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000000000000000
WITH PERMISSION_SET = SAFE;
END;
PRINT ' Altering Database to set TRUSTWORTHY back to OFF...';
ALTER DATABASE [SQLCLRvsClrStrictSecurity]
SET TRUSTWORTHY OFF;
PRINT N' Creating [dbo].[Date_Format]...';
EXEC(N'
CREATE FUNCTION [dbo].[Date_Format]
(
@DateToFormat DATETIME,
@FormatString NVARCHAR(500)
)
RETURNS NVARCHAR(MAX)
WITH EXECUTE AS CALLER,
RETURNS NULL ON NULL INPUT
AS EXTERNAL NAME [SQL2017_TrustedAssemblies].[SQL2017vsSQLCLR].[Date_Format];
');
--PRINT ' Altering Database to set TRUSTWORTHY back to OFF...';
--ALTER DATABASE [SQLCLRvsClrStrictSecurity]
-- SET TRUSTWORTHY OFF;
END;
GO
-- TEST A
-- Should error due to:
-- 1) "clr strict security" is enabled
-- 2) TRUSTWORTHY is disabled
-- 3) Assembly is not signed (hence no signature-based Login)
-- 4) This is not a "Trusted" Assembly
PRINT CHAR(13) + CHAR(10) + 'Running test A...';
GO
SELECT dbo.Date_Format('2017-08-12 14:15:16.789', N'~~ yyyy ~~ d ~~ MMM ~~ mm ~~') AS [DateFormatOutput];
-- error:
/*
Msg 10314, Level 16, State 11, Server osboxes, Line XXXXX
An error occurred in the Microsoft .NET Framework while trying to load assembly id 65546. The server may be running out of
resources, or the assembly may not be trusted. Run the query again, or check documentation to see how to solve the
assembly trust issues. For more information about this error:
System.IO.FileLoadException: Could not load file or assembly 'sql2017_trustedassemblies, Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)
System.IO.FileLoadException:
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly
locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection,
Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence asse
*/
GO
-- SETUP FOR TEST B (B1 and B2)
-- 1) Create Certificate
-- 2) Sign Assembly
-- 3) Copy Certificate to [master] (Public Key only!)
-- 4) Create Login from Certificate
-- DROP SIGNATURE FROM Assembly::[SQL2017_TrustedAssemblies] BY CERTIFICATE [SQL2017-TrustedAssemblies];
-- DROP CERTIFICATE [SQL2017-TrustedAssemblies-Cert];
IF (SUSER_ID(N'SQL2017-TrustedAssemblies-Login') IS NULL)
BEGIN
PRINT CHAR(13) + CHAR(10) + 'Permission Login does NOT exist:';
IF (CERT_ID(N'SQL2017-TrustedAssemblies-Cert') IS NULL)
BEGIN
PRINT ' Creating Certificate in [SQLCLRvsClrStrictSecurity]...';
CREATE CERTIFICATE [SQL2017-TrustedAssemblies-Cert]
ENCRYPTION BY PASSWORD = 'YaddaYaddaYadda!'
WITH SUBJECT = 'Sql Quantum Leap',
EXPIRY_DATE = '2099-12-31';
END;
IF (NOT EXISTS(
SELECT *
FROM sys.crypt_properties cp
INNER JOIN sys.assemblies sa
ON sa.[assembly_id] = cp.[major_id]
WHERE sa.[name] = N'SQL2017_TrustedAssemblies'
))
BEGIN
PRINT ' Signing the Assembly...';
ADD SIGNATURE
TO Assembly::[SQL2017_TrustedAssemblies]
BY CERTIFICATE [SQL2017-TrustedAssemblies-Cert]
WITH PASSWORD = 'YaddaYaddaYadda!';
END;
IF (NOT EXISTS(
SELECT *
FROM [master].[sys].[certificates] crt
WHERE crt.[name] = N'SQL2017-TrustedAssemblies-Cert'
))
BEGIN
PRINT ' Copying the Certificate to [master]...';
DECLARE @PublicKey VARBINARY(MAX),
@SQL NVARCHAR(MAX);
SET @PublicKey = CERTENCODED(CERT_ID(N'SQL2017-TrustedAssemblies-Cert'));
SET @SQL = N'
CREATE CERTIFICATE [SQL2017-TrustedAssemblies-Cert]
FROM BINARY = ' + CONVERT(NVARCHAR(MAX), @PublicKey, 1) + N';';
--SELECT @PublicKey AS [@PublicKey]; -- DEBUG
--PRINT @SQL; -- DEBUG
EXEC [master].[sys].[sp_executesql] @SQL;
END;
PRINT ' Creating permissions Login...';
EXEC [master].[sys].[sp_executesql] N'
CREATE LOGIN [SQL2017-TrustedAssemblies-Login]
FROM CERTIFICATE [SQL2017-TrustedAssemblies-Cert];
';
END;
GO
-- TEST B1
-- Should error due to:
-- 1) "clr strict security" is enabled
-- 2) TRUSTWORTHY is disabled
-- 3) Signature-based Login does not have "UNSAFE ASSEMBLY" permission
-- 4) This is not a "Trusted" Assembly
PRINT CHAR(13) + CHAR(10) + 'Running test B1...';
GO
SELECT dbo.Date_Format('2017-08-12 14:15:16.789', N'~~ yyyy ~~ d ~~ MMM ~~ mm ~~') AS [DateFormatOutput];
-- error
/*
{ same as shown above for Test A }
*/
GO
-- SETUP FOR TEST B2
-- 5) Grant Login UNSAFE ASSEMBLY permission
PRINT CHAR(13) + CHAR(10) + 'Granting UNSAFE ASSEMBLY permission...';
-- REVOKE UNSAFE ASSEMBLY FROM [SQL2017-TrustedAssemblies-Login];
EXEC [master].[sys].[sp_executesql] N'
GRANT UNSAFE ASSEMBLY TO [SQL2017-TrustedAssemblies-Login]; -- REQUIRED!!!!
';
PRINT CHAR(13) + CHAR(10) + 'Running test B2...';
GO
SELECT dbo.Date_Format('2017-08-12 14:15:16.789', N'~~ yyyy ~~ d ~~ MMM ~~ mm ~~') AS [DateFormatOutput];
/* RETURNS:
~~ 2017 ~~ 12 ~~ Aug ~~ 15 ~~
*/
GO
PRINT '';
SELECT ASSEMBLYPROPERTY(N'SQL2017_TrustedAssemblies', 'CLRName') AS [CLRName];
-- sql2017_trustedassemblies, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil
-----------------------------------------------------------
-- Clean up:
PRINT CHAR(13) + CHAR(10) + 'Cleaning up objects (to be re-runnable)...';
USE [SQLCLRvsClrStrictSecurity];
DROP FUNCTION [dbo].[Date_Format];
DROP ASSEMBLY [SQL2017_TrustedAssemblies];
DROP CERTIFICATE [SQL2017-TrustedAssemblies-Cert];
USE [master];
DROP LOGIN [SQL2017-TrustedAssemblies-Login];
DROP CERTIFICATE [SQL2017-TrustedAssemblies-Cert];
-- DROP DATABASE [SQLCLRvsClrStrictSecurity];
Comments
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎
0 B
|👍
/👎