CLR的SQL Server 2017年
MSDN上严格的安全性上this article说:CLR的SQL Server 2017年
CLR在.NET Framework,这是毫无 不再支持作为一个安全边界使用代码访问安全(CAS)。使用 PERMISSION_SET = SAFE创建的CLR程序集可能能够访问外部系统资源, 调用非托管代码并获取系统管理员权限。从 开始,为了增强CLR程序集的安全性,引入了一个名为clr strict security的sp_configure选项 。 clr strict 默认情况下启用安全性,并将SAFE和EXTERNAL_ACCESS 程序集视为标记为UNSAFE。为了向后兼容,可以禁用clr严格安全 选项,但建议不要使用 。 Microsoft建议所有程序集均使用 证书或非对称密钥进行签名,并在master数据库中使用相应的登录名,授予了UNSAFE ASSEMBLY权限 。
使用PERMISSION_SET = SAFE
创建的CLR程序集如何能够访问外部系统资源,调用非托管代码并获取系统管理员权限?
为什么不再支持CAS作为安全边界?
据我所知,CLR程序集不再安全,这是非常不幸的。
如何用PERMISSION_SET = SAFE创建的CLR程序集可以访问外部系统资源,调用非托管代码并获取系统管理员权限?
这是由于在.NET Framework中进行的安全更改(从4.5版开始)(我相信)。
MSDN文档Code Access Security Basics状态:
.NET Framework提供了信任的不同层次的不同代码,称为代码访问安全性(CAS)相同的应用程序中运行的实施机制。不应将.NET Framework中的代码访问安全性用作基于代码起源或其他身份方面强制执行安全边界的机制。我们正在更新我们的指导意见,以反映代码访问安全和安全透明代码将不被支持作为具有部分可信代码的安全边界,尤其是未知来源的代码。我们建议不要加载和执行未知来源的代码,而不采取其他安全措施。
然后指向页面Security Changes in the .NET Framework其中规定:
在.NET Framework 4.5的安全性最重要的变化是强命名。
,然后指向它规定为Enhanced Strong Naming的文档:
强名称密钥由一个签名密钥和身份密钥。程序集使用签名密钥进行签名,并通过身份密钥进行标识。在.NET Framework 4.5之前,这两个密钥是相同的。从.NET Framework 4.5开始,身份密钥与早期的.NET Framework版本保持一致,但签名密钥使用更强大的哈希算法进行了增强。另外,签名密钥用身份密钥签名以创建一个反签名。
而且,Secure Coding Guidelines状态的文档:
代码访问安全和安全透明的代码将不被支持与部分受信任的代码中的安全边界。我们建议不要装载和执行未知来源的代码,而不采取其他安全措施......
因此,.NET的安全模型在几年前就已改变,但SQL Server(直到SQL Server 2017)已被允许继续使用旧的安全模型。看来,从SQL Server 2017开始,决定不再支持旧的安全模型。
我怀疑,让旧的安全模式是:
防止SQL服务器(至少CLR相关的功能/组件)被基于较新版本的.NET Framework,并
负责突然去除SQLCLR的从Azure中的SQL数据库支持的功能(支持已在2014年年底加入推出V12,但后来完全去除,2016年4月15日的)。
所以,是的,这有点儿吸。这意味着什么(至少暂时)是一个需要第一创建证书或非对称密钥(已用于签名被加载任何组件)到[master]
来,然后创建一个登录,然后授予UNSAFE ASSEMBLY
到该登录。这是相同的事件序列一个装载EXTERNAL_ACCESS
和UNSAFE
组件时,但现在,不幸的是,需求甚至SAFE
大会做需要做的。
目前没有机制能够移植到处理此(即,不依赖于外部文件),并且不能由Visual Studio/SSDT无需手动干预来处理。事实上,情况已经如此了,但至少可以创建一个设置来以完全便携的方式处理这个问题(即完全包含在.sql脚本中):请参阅Stairway to SQLCLR Level 7: Development and Security以获取详细信息(这是我写的一篇文章)。
它可以创建从十六进制字节的证书(即FROM BINARY = 0x...
),但/ SSDT因为使用证书需要使用signtool
不与Visual Studio(其依赖于MSBuild的)工作,并且使用的MSBuild sn
。
为了使它成为可行的,以便Visual Studio/MSBuild/SSDT发布过程起作用(这反过来意味着任何人都可以创建一个完全自包含的.sql脚本,能够创建非对称密钥不依赖于外部文件),CREATE ASYMMETRIC KEY
命令需要增强以允许从二进制字符串创建。我已经对微软连接这个建议– Allow Asymmetric Key to be created from binary hex bytes string just like CREATE CERTIFICATE –所以请支持它:-)。或者(现在,直到MS希望创建一个更好的方法,比如我的非对称密钥建议),您可以尝试我在以下博客文章中描述的两种技术中的任何一种(均可与SSDT一起使用):
- SQLCLR vs. SQL Server 2017, Part 2: “CLR strict security” – Solution 1
- SQLCLR vs. SQL Server 2017, Part 3: “CLR strict security” – Solution 2
作为最后的手段,可以考虑以下方法:
-
TEMPORARILY设置
[master]
数据库到TRUSTWORTHY ON
- 创建大会
[master]
- 创建一个从大会
- 降的非对称密钥大会
- 设置
[master]
数据库到TRUSTWORTHY OFF
- 从不对称密钥创建登录
- 格兰特
UNSAFE ASSEMBLY
到登录
请注意,我没有不包括新的“可信大会”功能作为一个不错的选择。没有提及的原因是它有更多的缺点而不是好处,更不用说它首先是完全没有必要的,因为现有的功能已经处理了“可信大会”旨在解决的情况。有关详细信息以及处理现有未签名程序集的正确方法演示,请参阅:SQLCLR vs. SQL Server 2017, Part 4: “Trusted Assemblies” – The Disappointment。
我前几天看到这个消息,看起来并不像听起来那么糟糕(除了你不能再创建一个SAFE程序集,但需要签署它等等,或者使用TRUSTWORTHY )。
在我的测试:
- 我创建了一个“安全”的方法以及“不安全” 的组件(它使用的任务)。
- 我创建的程序集是安全的(因建后签署 等)
- 我创造了我的身边两种方法T-SQL包装功能。
- 执行“安全”功能时,所有工作。
- 执行“不安全”时,我收到一个HostProtectionException。
对我来说,这表示仍然有一些控制什么正在执行。我遵循的增长:
与PERMISSION_SET =不安全- 重新创建装配
- 现在,当我执行不安全的功能都如预期的工作。
所以我不太确定“clr严格安全性”文档中的声明是否100%正确。
我写的我的经验博客,帖子,你可以在这里找到它,如果你想测试一下你自己:http://www.nielsberglund.com/2017/07/02/sql-server-2017-sqlclr-and-permissions/
尼尔斯
非常漂亮的博客,帖子,非常感谢你。所以你认为这句话“可能能够访问外部系统资源,调用非托管代码并获得系统管理员权限”是不正确的。也许你需要做一些奇特的事来绕过安全检查 –
嗨耶!是的 - 我认为这是不正确的,至少不是基于我的测试。 –