是否可以将 .net dll 以不安全的方式加载到 SQL Server 中?
创建 SQL Server CLR 存储过程时,我注意到我无法像平常那样引用 .net 框架中的任何内容。 经过一番阅读后,我意识到需要首先将程序集加载到数据库中。
因此,我加载了我需要的内容,但由于 P/Invoke 必须使用 UNSAFE 权限集。 我现在可以在我的存储过程代码中引用它们,并且一切正常。
然而,当我真的不知道他们在做什么时,我有点担心必须将它们设置为不安全。 所以我的问题是:
是否可以将 .net 框架加载为 UNSAFE 而不确切地知道它正在做什么? 这样做会如何损害 sql server 的安全性/稳健性/可扩展性(正如微软警告的那样)?
非常感谢。
When creating a SQL Server CLR stored procedure, I noticed that I couldn't reference anything in the .net framework as I would normally. After some reading around, I realised that assemblies needed to be loaded into the database first.
Therefore, I loaded in the ones I need but due to P/Invoke had to use the UNSAFE permission set. I can now reference them in my stored procedure code and everything works fine.
However, I'm a little concerned about having to set them to UNSAFE when I don't really know what they are doing. So my question is this:
Is it ok to load the .net framework in as UNSAFE without exactly what it's doing?
And how would doing so compromise security/robustness/scalability of sql server (as microsoft warn it could)?
Many thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它可以更改注册表、重新启动服务、重新启动服务器等。没什么太重要的;-)一个简单的 差异图表
也请参阅此问题(尽管没有答案)SQL Server 2008:加载非托管库的 CLR 存储过程的崩溃安全性如何
当然,你在做什么需要不安全的访问?
It could change the registry, restart services, reboot the server etc. Nothing too important ;-) A simple chart with the differences
See this question too (no answers though) SQL Server 2008: How crash-safe is a CLR Stored Procedure that loads unmanaged libraries
Of course, what are you doing that requires UNSAFE access?
当您在托管许多公共网站的服务器上使用 SQL 数据库引擎时,您作为服务器管理员(或 DBA 或任何负责人)对此一无所知,您应该限制他们的访问,这该死的很重要! 此外,如果您的 DBA 所在的领域是某些大公司中数据最为重要的受限领域,那么这也是最重要的。
在我看来,你应该给你的应用程序提供它需要看到的内容,仅此而已。 例如,如果您不需要查看注册表,为什么要给予程序集不受限制的访问权限? 您不知道如果有人注入您的应用程序代码并劫持数据库(而且访问权限不受限制!),会有多危险。
希望能帮助到你
When you use the SQL database engine on a server which is hosting many many public websites you don't know anything about as a server administrator (or DBA or whoever responsible), you should restrict their access and damn it's important! Also if you have a DBA in a restricted area, where data matters the most in some big companies, again it's the most important thing.
In my point of view, you should give your application as it needs to see, nothing more. If you don't need to see the registry for example, why you wanna give unrestricted access to the assembly? You have no idea how dangerous it could be if somebody injects the code of your application and hijack into the database (also with an unrestricted access!).
Hope it helps
此问题特定于加载不在 支持的集合中的 .Net Framework 程序集.NET Framework 库,因此我将重点关注 Microsoft 提供的 DLL 上下文,而不是任何随机 DLL。
“支持”列表中的程序集与列表中未列出的程序集之间的差异归结为以下事实:受支持的程序集“已经过测试,以确保它们满足与 SQL Server 交互的可靠性和安全标准”(如上面链接的“支持的库”页面)。 主要问题更多的是“可靠性”而不是“安全性”。 支持列表中的程序集已经过验证,其行为与预期一致,并且没有任何错误或奇怪的副作用。 该功能已经过测试,可以与各种语言和排序规则等配合使用。
某些不在受支持列表中的 .Net Framework 程序集可以通过设置为
SAFE
的PERMISSION_SET
进行加载。 然而,这并不能保证期望的行为。 有些可以作为UNSAFE
加载,但不一定表明会出现问题。作为不保证行为的示例:我加载了 System.Drawing 以便进行一些简单的图像操作。 我测试了直接通过
byte[]
/VARBINARY(MAX)
提供图像以及由文件路径提供并从磁盘读取图像时的操作。 一切都按预期进行。 我将其发送给德国的某个人,他的 Windows 和 SQL Server 的语言都设置为“德语”。 直接提供图像时,他能够得到预期的结果。 但是当他提供文件路径时它不起作用。对于不良行为,当您尝试执行此操作时,SQL Server 将显示程序集无法以
SAFE
或EXTERNAL_ACCESS
方式加载的原因。 例如:结果:
如果您不打算使用任何这些方法或类型,那么您可能不会遇到任何问题。 没有办法将“安全”的东西与“不安全”的东西分开。
关联有罪的另一个例子,但更远的是:
结果:
正如您所看到的,
System.Web
本身对于SAFE
来说确实很好,但它有依赖的程序集,并且这些程序集是自动加载的。 第一个依赖程序集 microsoft.build.framework 也没有问题(至少无法验证,尽管可能存在 SAFE 中不允许的内容)但只能在运行时捕获)。 但第二个依赖程序集确实存在一个可以在加载程序集时验证的问题:它“存储到静态字段”。 这是一个可靠性问题,而不是安全性问题,因为类被实例化一次(好吧,每个应用程序域,意思是:每个数据库,每个所有者)并在 SPID 之间共享以供使用(这就是为什么在 SQLCLR 中只能访问静态方法的原因) 。 因此,静态类级变量在技术上在会话(即 SPID)之间共享信息,这很容易导致意外行为。 但同时,如果您只想使用HtmlString.ToHtmlString()
,那么您可能没有使用System.Xaml
。 那么为什么它不将System.Web
加载为SAFE
并将System.Xaml
加载为UNSAFE
呢? 可能是因为SAFE
程序集中的代码不允许调用UNSAFE
程序集中的代码(至少在 SQLCLR 中不允许)。结论
那么加载
UNSAFE
.Net Framework 程序集是否可以? 这确实应该归结为测试。 大量测试(不仅仅是开发盒上的单个线程,而是真实测试)。 如果一切都按预期进行,那么你应该没问题。 但是,如果某些内容没有按预期运行,那么它就不是可以向 Microsoft 报告的错误,因为它已被声明为不受支持。编辑:
以下是对此问题的更官方答案,其中列出了可能发生问题的几种情况:对 SQL Server CLR 托管环境中未经测试的 .NET Framework 程序集的支持策略
This question is specific to loading .Net Framework assemblies that are not in the set of Supported .NET Framework Libraries, so I will focus on the context being Microsoft supplied DLLs rather than any random DLL.
The difference between the assemblies in the "Supported" list and those not in the list comes down to the fact that the supported ones "have been tested to ensure that they meet reliability and security standards for interaction with SQL Server" (as noted in the "Supported Libraries" page linked above). The main issue is more so the "reliability" than the "security". The assemblies in the supported list have been verified to behave consistently as expected and without any bugs or odd side-effects. The functionality has been tested to work with various languages and collations, etc.
Some .Net Framework assemblies that are not in the supported list can be loaded with a
PERMISSION_SET
set toSAFE
. This, however, does not guarantee desired behavior. And some can be loaded asUNSAFE
without necessarily indicating that there will be a problem.As an example of not guaranteeing behavior: I have loaded
System.Drawing
in order to do some simple image manipulation. I tested manipulations when the image was supplied directly viabyte[]
/VARBINARY(MAX)
as well as when it was supplied by a filepath and read from disk. Everything worked as expected. I sent that to someone in Germany whose Windows and SQL Server were both set to "German" as the language. He was able to get the expected results when supplying the image directly. But when he supplied a filepath it didn't work.And regarding undesired behavior, SQL Server will display the reasons why the assembly can't load as either
SAFE
orEXTERNAL_ACCESS
when you try to do it. For example:Results in:
If you are not going to use any of those methods or types, then you likely will not have any issues. There is just no way to separate out the "safe" stuff from the "unsafe" items.
Another example of guilt-by-association, but even farther removed, is:
Results in:
As you can see,
System.Web
is actually, by itself, fine forSAFE
, but it has dependent assemblies and those are being auto-loaded. The first dependent assembly,microsoft.build.framework
also has no issues (at least not that can be verified, though it is possible that something that is disallowed inSAFE
is there but can only be caught at run-time). But the second dependent assembly does have an issue that can be verified upon loading the assembly: it is "storing to a static field". This is a problem for reliability more than security because classes are instantiated one time (well, per App Domain, meaning: per-database, per owner) and shared across the SPIDs to use (which is why only static methods are accessible in SQLCLR). Hence, static class-level variables are technically sharing information between sessions (i.e. SPIDs) and that can very easily cause unexpected behavior. But at the same time, if you only want to useHtmlString.ToHtmlString()
, then you probably aren't making use ofSystem.Xaml
. So why doesn't it just loadSystem.Web
asSAFE
andSystem.Xaml
asUNSAFE
? Probably because code inSAFE
assemblies is not allowed to call code inUNSAFE
assemblies (at least not in SQLCLR).CONLUSION
So is it OK to load
UNSAFE
.Net Framework assemblies? That really should come down to testing. Lots of testing (and not just a single thread on your dev box, but real testing). If everything behaves as expected then you should be fine. But, if something does not behave as expected, then it is not a bug that can be reported to Microsoft because it has already been declared as unsupported.EDIT:
And here is a more official answer to this question, which lists a few situations where problems could occurr: Support policy for untested .NET Framework assemblies in the SQL Server CLR-hosted environment