The ability to load and execute managed code in a SQL Server host requires meeting the host's requirements for both code access security and host resource protection. The code access security requirements are specified by one of three SQL Server permission sets: SAFE, EXTERNAL-ACCESS, or UNSAFE. Code executing within the SAFE or EXTERNAL-ACCESS permission sets must avoid certain types or members that have the HostProtectionAttribute attribute applied. The HostProtectionAttribute is not a security permission as much as a reliability guarantee in that it identifies specific code constructs, either types or methods, that the host may disallow. The use of the HostProtectionAttribute enforces a programming model that helps protect the stability of the host.
Host protection attributes identify types or members that do not fit the host programming model and represent the following increasing levels of reliability threat:
Are otherwise benign.
Could lead to destabilization of server-managed user code.
Could lead to destabilization of the server process itself.
SQL Server disallows the use of a type or member that has a HostProtectionAttribute that specifies a HostProtectionResource value of SharedState, Synchronization, MayLeakOnAbort, or ExternalProcessMgmt. This prevents the assemblies from calling members that enable sharing state, perform synchronization, might cause a resource leak on termination, or affect the integrity of the SQL Server process.
The following table identifies types and members whose HostProtectionResource values are disallowed by SQL Server.
Namespace
Type or member
Microsoft.Win32
PowerModeChangedEventArgs class
PowerModeChangedEventHandler delegate
SessionEndedEventArgs class
SessionEndedEventHandler delegate
SessionEndingEventArgs class
SessionEndingEventHandler delegate
SessionSwitchEventArgs class
SessionSwitchEventHandler delegate
SystemEvents class
TimerElapsedEventArgs class
TimerElapsedEventHandler delegate
UserPreferenceChangedEventArgs class
UserPreferenceChangingEventArgs class
System.Collections
ArrayList..::.Synchronized method
Hashtable..::.Synchronized method
Queue..::.Synchronized method
SortedList..::.Synchronized method
Stack..::.Synchronized method
System.ComponentModel
AddingNewEventArgs class
AddingNewEventHandler delegate
ArrayConverter class
AsyncCompletedEventArgs class
AsyncCompletedEventHandler delegate
AsyncOperation class
AsyncOperationManager class
AttributeCollection class
BackgroundWorker class
BaseNumberConverter class
BindingList<(Of <(T>)>) class
BooleanConverter class
ByteConverter class
CancelEventArgs class
CancelEventHandler delegate
CharConverter class
CollectionChangeEventArgs class
CollectionChangeEventHandler delegate
CollectionConverter class
ComponentCollection class
ComponentConverter class
ComponentEditor class
ComponentResourceManager class
Container class
ContainerFilterService class
CultureInfoConverter class
CustomTypeDescriptor class
DateTimeConverter class
DecimalConverter class
ActiveDesignerEventArgs class
ActiveDesignerEventHandler delegate
CheckoutException class
CommandID class
ComponentChangedEventArgs class
ComponentChangedEventHandler delegate
ComponentChangingEventArgs class
ComponentChangingEventHandler delegate
ComponentEventArgs class
ComponentEventHandler delegate
ComponentRenameEventArgs class
ComponentRenameEventHandler delegate
DesignerCollection class
DesignerEventArgs class
DesignerEventHandler delegate
DesignerOptionService class
DesignerTransaction class
DesignerTransactionCloseEventArgs class
DesignerTransactionCloseEventHandler delegate
DesignerVerb class
DesignerVerbCollection class
DesigntimeLicenseContext class
DesigntimeLicenseContextSerializer class
MenuCommand class
ComponentSerializationService class
ContextStack class
DesignerLoader class
InstanceDescriptor class
MemberRelationshipService class
ResolveNameEventArgs class
ResolveNameEventHandler delegate
SerializationStore class
ServiceContainer class
ServiceCreatorCallback delegate
StandardCommands class
StandardToolWindows class
DoubleConverter class
DoWorkEventArgs class
DoWorkEventHandler delegate
EnumConverter class
EventDescriptor class
EventDescriptorCollection class
EventHandlerList class
ExpandableObjectConverter class
HandledEventArgs class
HandledEventHandler delegate
InstanceCreationEditor class
Int16Converter class
Int32Converter class
Int64Converter class
InvalidAsynchronousStateException class
InvalidEnumArgumentException class
BeginInvoke method
License class
LicenseContext class
LicenseException class
LicenseManager class
LicenseProvider class
LicFileLicenseProvider class
ListChangedEventArgs class
ListChangedEventHandler delegate
ListSortDescription class
ListSortDescriptionCollection class
MaskedTextProvider class
MemberDescriptor class
MultilineStringConverter class
NestedContainer class
NullableConverter class
ProgressChangedEventArgs class
ProgressChangedEventHandler delegate
PropertyChangedEventArgs class
PropertyChangedEventHandler delegate
PropertyDescriptor class
PropertyDescriptorCollection class
ReferenceConverter class
RefreshEventArgs class
RefreshEventHandler delegate
RunWorkerCompletedEventArgs class
RunWorkerCompletedEventHandler delegate
SByteConverter class
SingleConverter class
StringConverter class
SyntaxCheck class
TimeSpanConverter class
TypeConverter class
TypeDescriptionProvider class
TypeDescriptor class
TypeListConverter class
UInt16Converter class
UInt32Converter class
UInt64Converter class
WarningException class
Win32Exception class
System.Diagnostics
Debug..::.Listeners property
Trace..::.Listeners property
EventLog..::.SynchronizingObject property
ConsoleTraceListener class
DefaultTraceListener class
DelimitedListTraceListener class
EventLogTraceListener class
PerformanceCounter class
PerformanceCounterCategory class
Process class
ProcessStartInfo class
TextWriterTraceListener class
TraceListener class
XmlWriterTraceListener class
TraceSource..::.Listeners property
System.IO
Stream..::.Synchronized method
TextReader..::.Synchronized method
TextWriter..::.Synchronized method
System.Reflection.Emit
ConstructorBuilder class
EventBuilder class
FieldBuilder class
MethodBuilder class
CustomAttributeBuilder class
MethodRental class
ModuleBuilder class
PropertyBuilder class
TypeBuilder class
UnmanagedMarshal class
System.Text
Group..::.Synchronized method
Match..::.Synchronized method
System.Threading
AutoResetEvent class
EventWaitHandle class
ManualResetEvent class
Monitor class
Mutex class
ReaderWriterLock class
Semaphore class
Thread..::.AllocateNamedDataSlot method
Thread..::.BeginCriticalRegion method
Thread..::.EndCriticalRegion method
Thread..::.FreeNamedDataSlot method
Thread..::.GetData method
Thread..::.Join method
Thread..::.SetApartmentState method
Thread..::.SetData method
Thread..::.SpinWait method
Thread..::.Start method
Thread..::.TrySetApartmentState method
ThreadPool class
Timer class
System.Timers
System.Web.Configuration
MachineKeyValidationConverter class
System.Windows.Forms
AutoCompleteStringCollection..::.SyncRoot property
SQL Server allows users to specify the reliability requirements for code deployed into a database. When assemblies are uploaded into the database, the author of the assembly can specify one of three permission sets for that assembly: SAFE, EXTERNAL-ACCESS, or UNSAFE.
Permission set
SAFE
EXTERNAL-ACCESS
UNSAFE
Code access security
Execute only
Execute + access to external resources
Unrestricted
Programming model restrictions
Yes
No restrictions
Verifiability requirement
No
Ability to call native code
SAFE is the most reliable and secure mode with associated restrictions in terms of the allowed programming model. SAFE code has high reliability and security features. SAFE assemblies are given enough permission to run, perform computations, and have access to the local database. SAFE assemblies need to be verifiably type safe and are not allowed to call unmanaged code.
EXTERNAL-ACCESS provides an intermediate security option, allowing code to access resources external to the database but still having the reliability and safety of SAFE.
UNSAFE is for highly trusted code that can only be created by database administrators. This trusted code has no code access restrictions, and it can call unmanaged (native) code.
SQL Server uses the host-level code access security policy layer to set up a host policy that grants one of the three sets of permissions based on the permission set stored in SQL Server catalogs. Managed code running inside the database always gets one of these code access permission sets.
The programming model for managed code in SQL Server requires functions, procedures, and types which do not require the use of state held across multiple invocations or the sharing of state across multiple user sessions. Further, as described earlier, the presence of shared state can cause critical exceptions that impact the scalability and the reliability of the application.
Given these considerations, SQL Server disallows the use of static variables and static data members. For SAFE and EXTERNAL-ACCESS assemblies, SQL Server examines the metadata of the assembly at CREATE ASSEMBLY time, and fails the creation of such assemblies if it finds the use of static data members and variables.