8

I get the following errors in my development database:

A .NET Framework error occurred during execution of user-defined routine or aggregate "SpCreateTable": 
System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host.

The protected resources (only available with full trust) were: All
The demanded resources were: Synchronization, ExternalThreading

Is the correct solution to set trustworthy = on? What are security concerns with this?

Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
cdub
  • 24,555
  • 57
  • 174
  • 303

2 Answers2

11

The TRUSTWORTHY property of a database (when set to ON) essentially declares to SQL Server that code contained within that database, and executing in an impersonated context, should be allowed to reach outside of that database while maintaining that impersonated security context. It also allows for all SQLCLR Assemblies in that Database to be set to EXTERNAL_ACCESS and UNSAFE, whether or not that code reaches outside of the server (outside meaning: network access, file system access, registry access, environment access, etc).

It is a rather generic means of allowing for this as it covers all code within the database. Using Certificates and/or Asymmetric Keys to sign modules--procs and/or assemblies--allow for more granular control over what code has what permissions.

Setting a Database to TRUSTWORTHY also allows any process starting in this Database to reach up to the Server-level and/or across to other Databases. Normally a process is confined / quarantined to the Database where it started. If the Database is owned by the "sa" Login, then any process initiated in that Database and running as "dbo" will effectively have "sa" privileges (yikes!).

Rather than trying to describe here, in the amount of detail required to fully communicate the specifics about impersonation, extending said impersonation, signing modules, etc, I recommend perusing the following resources on this topic:

You should avoid setting your database to TRUSTWORTHY as much as possible. If you really must have multithreading / async calls AND if you have the source code and are compiling the assembly, then I cannot think of a reason to use the SET TRUSTWORTHY ON option. Instead, you should sign the assembly with a password and use the following commands to set up the preferred method of allowing EXTERNAL_ACCESS and UNSAFE assemblies:

USE [master];
  CREATE ASYMMETRIC KEY [ClrPermissionsKey]
    AUTHORIZATION [dbo]
    FROM EXECUTABLE FILE = 'C:\path\to\my\assembly.dll';

CREATE LOGIN [ClrPermissionsLogin]
  FROM ASYMMETRIC KEY [ClrPermissionsKey];

GRANT UNSAFE ASSEMBLY TO [ClrPermissionsLogin];

Once that is in place, you can go to the database where your assembly has been loaded and run:

ALTER ASSEMBLY [MyAssembly] WITH PERMISSION_SET = UNSAFE;

Or you could have included WITH PERMISSION_SET = UNSAFE at the end of the CREATE ASSEMBLY command.

Solomon Rutzky
  • 46,688
  • 9
  • 128
  • 171
  • They actually are signed with an asymmetric key and set to unsafe but still get that error. not sure why – cdub Nov 19 '14 at 01:36
  • 2
    +1 for offering a valid workaround, but you haven't really addressed the real question (specific and explicit risks about TRUSTWORTHY in general). – Aaron Bertrand Nov 19 '14 at 03:11
  • @chris Are you sure that the assembly is set to UNSAFE? The error you posted is what you get when the assembly is not set to unsafe. Or, when it was set to UNSAFE but then the Login was removed or at least had the `UNSAFE ASSEMBLY` permission removed. If any of that is not the case, then what framework methods are you calling in your proc method? – Solomon Rutzky Nov 19 '14 at 03:27
  • @AaronBertrand : Thanks. And I have now updated the answer to provide some details and links to more info regarding implications of TRUSTWORTHY. – Solomon Rutzky Nov 19 '14 at 05:38
  • Solomon, and Aaron how do you register System.DirectoryServices.AccountManagement.dll on SQL Server 2016 without using TRUSTWORTHY? I have tried, and tried but cannot seem to make it work with an ASYMMETRIC key. – SpaceGhost440 Feb 28 '19 at 19:17
  • @SpaceGhost440 I have an answer here somewhere that shows how to do that. Lemme find it and I will paste a link for it here. Of course, this assumes that `System.DirectoryServices.AccountManagement` is a pure-MSIL assembly. If not, then there is no way to load it no matter what. – Solomon Rutzky Feb 28 '19 at 19:35
  • @SpaceGhost440 I answered [your question on DBA.SE](https://dba.stackexchange.com/a/230995/30859) instead. – Solomon Rutzky Feb 28 '19 at 19:52
0

Setting TRUSTWORTHY ON opens a potential security breach by allowing any code to reach external resources under database impersonation context. It's perfectly fine to allow your DB to access protected network shares using a code you're in control of, however it might be not that wise to allow the same for any code.

Setting this flag just opens a door for anyone gained dbo permissions for a particular DB as you might register any assembly and it'll have DB impersonation context at its discretion.

Vitaly
  • 813
  • 10
  • 17