CLR 集成编程模型限制

Applies to:SQL ServerAzure SQL Managed Instance

生成托管存储过程或其他托管数据库对象时,SQL Server 会执行需要考虑的某些代码检查。 首次在数据库中注册、使用 CREATE ASSEMBLY 语句和运行时时,对托管代码程序集执行这些检查。 在运行时还会检查托管代码,因为在程序集中,可能从未在运行时实际访问过代码路径。

These code checks provide flexibility for registering third-party assemblies especially, so that an assembly isn't blocked where there's unsafe code designed to run in a client environment, but would never be executed in the hosted common language runtime (CLR). 托管代码必须满足的要求取决于程序集是注册为 SAFEEXTERNAL_ACCESS还是 UNSAFESAFE 是最严格的安全级别。

除了对托管代码程序集进行了限制,还授予了一些代码安全权限。 CLR 支持一种用于托管代码的安全模型,称为代码访问安全性 (CAS)。 在这种模式下,根据代码的标识来对程序集授予权限。 SAFEEXTERNAL_ACCESSUNSAFE 程序集具有不同的 CAS 权限。 有关详细信息,请参阅 CLR 集成代码访问安全性

If the publisher policy is set, CREATE ASSEMBLY fails.

不再支持代码访问安全性

CLR 在 .NET Framework 中使用代码访问安全性 (CAS)(不可再作为安全边界)。 使用 PERMISSION_SET = SAFE 创建的 CLR 程序集可以访问外部系统资源、调用非托管代码以及获取 sysadmin 特权。 在 SQL Server 2017 (14.x) 及更高版本中,sp_configure 选项 clr strict security 增强了 CLR 程序集的安全性。 默认启用 clr strict security,并将 SAFEEXTERNAL_ACCESS 程序集与标记为 UNSAFE 的程序集同等对待。 可禁用 clr strict security 选项以实现后向兼容性,但不建议这样做。

我们建议所有程序集都通过证书或非对称密钥进行签名,且该证书或非对称密钥具有已在 UNSAFE ASSEMBLY 数据库中获得 master 权限的相应登录名。 SQL Server 管理员还可以将程序集添加到数据库引擎应信任的程序集列表。 For more information, see sys.sp_add_trusted_assembly.

CREATE ASSEMBLY 检查

CREATE ASSEMBLY运行语句时,将针对每个安全级别执行以下检查。 如果任何检查失败, CREATE ASSEMBLY 则失败并显示错误消息。

全局(任何安全级别)

所有被引用的程序集都必须满足下列一个或多个条件:

  • 程序集已在数据库中注册。

  • 程序集是受支持的程序集之一。 有关详细信息,请参阅 支持的 .NET Framework 库

  • 你正在使用 CREATE ASSEMBLY FROM <location>,并且所有引用的程序集及其依赖项都可用 <location>

  • 你正在使用 CREATE ASSEMBLY FROM <bytes ...>,并且所有引用都通过空格分隔的字节指定。

EXTERNAL_ACCESS

所有 EXTERNAL_ACCESS 程序集都必须满足以下条件:

  • 静态字段不用于存储信息。 允许只读静态字段。

  • PEVerify 测试通过。 PEVerify 工具(peverify.exe用于检查公共中间语言(CIL)代码和相关元数据是否满足类型安全要求,随 .NET Framework SDK 一起提供。

  • 不使用同步(例如,与类一起 SynchronizationAttribute )。

  • 不使用终结器方法。

EXTERNAL_ACCESS 程序集中不允许以下自定义属性:

  • System.ContextStaticAttribute
  • System.MTAThreadAttribute
  • System.Runtime.CompilerServices.MethodImplAttribute
  • System.Runtime.CompilerServices.CompilationRelaxationsAttribute
  • System.Runtime.Remoting.Contexts.ContextAttribute
  • System.Runtime.Remoting.Contexts.SynchronizationAttribute
  • System.Runtime.InteropServices.DllImportAttribute
  • System.Security.Permissions.CodeAccessSecurityAttribute
  • System.Security.SuppressUnmanagedCodeSecurityAttribute
  • System.Security.UnverifiableCodeAttribute
  • System.STAThreadAttribute
  • System.ThreadStaticAttribute

SAFE

  • 检查所有 EXTERNAL_ACCESS 程序集条件。

Runtime checks

在运行时,将针对下列条件检查代码程序集。 如果找到上述任何条件,则不允许运行托管代码,并引发异常。

UNSAFE

不能通过从字节数组调用 System.Reflection.Assembly.Load() 方法或隐式使用 Reflection.Emit 命名空间来显式加载程序集。

EXTERNAL_ACCESS

检查所有 UNSAFE 条件。

在支持的程序集列表中不允许所有使用以下宿主保护属性 (HPA) 值批注的类型和方法。

  • SelfAffectingProcessMgmt
  • SelfAffectingThreading
  • Synchronization
  • SharedState
  • ExternalProcessMgmt
  • ExternalThreading
  • SecurityInfrastructure
  • MayLeakOnAbort
  • UI

有关 HPA 以及受支持程序集中不允许的类型和成员列表的详细信息,请参阅 主机保护属性和 CLR 集成编程

SAFE

检查所有 EXTERNAL_ACCESS 条件。