沙盒 AppDomain 跨程序集异常处理

Posted

技术标签:

【中文标题】沙盒 AppDomain 跨程序集异常处理【英文标题】:Sandbox AppDomain cross-assembly exception handling 【发布时间】:2014-11-22 13:14:15 【问题描述】:

我在沙盒应用程序域中遇到了一些异常问题。 在沙箱中运行的代码是安全透明的。 我有一个实用程序 dll,它允许部分受信任的调用者,并为 sanboxed 代码提供功能。它的方法是 SecuritySafeCritical。 一切正常,直到我们遇到例外情况。

在沙箱中运行的代码受到 try-catch 块的保护,因此如果 ti 抛出它不会导致应用程序崩溃。

如果安全透明 dll 中的代码抛出异常,一切正常。但是,如果沙盒代码调用受信任实用程序 dll 中的方法,并且该代码抛出异常,则会发生以下情况:

如果我在调试器中,调试器会中断:

An exception of type 'Blah' occurred in Trusted.dll but was not handled in user code

这本身是可以的,但是我的 try-catch 块捕获的异常不是“Blah”类型,但它是:

[System.Security.SecurityException] = "Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed."

我的猜测是,这种从受信任程序集到部分信任代码的异常“泄漏”是一个安全问题。我的第二个猜测是,这被认为是一个问题,因为介于两者之间的部分受信任代码可能会捕获异常,这可能会导致安全问题,从而阻止传播。 我不清楚的是,框架何时真正尝试断言导致上述异常引发的“SecurityPermission”。

我的问题:我应该如何处理这种情况?有没有办法让它以“干净”的方式工作(异常从可信 - 部分 - 可信代码一路传播),如果是这样,如何以安全的方式工作? (显然我不想盲目地断言权限,而不恢复它们!)

我有一个后备解决方案(我在我信任的助手中记录异常,抛出它,捕获安全异常,重新抛出原始异常)但我想知道是否有一个更干净的解决方案“符合规则”而不是弯曲它们。

如果我对跨汇编异常处理的猜测是正确的!

【问题讨论】:

【参考方案1】:

所以,原来是heisenbug,或者可能是相反的...

仅当我在调试器中运行我的代码时才会出现问题。沙盒似乎不喜欢在异常时中断然后在调试器中恢复它的行为。在调试器之外,只要您完成了作业(程序集是受信任的并添加到域受信任的程序集列表中,它允许部分受信任的调用者等),一切都会按预期工作。

另一个值得指出的问题:如果要保存异常并报告给调用appdomain,异常必须是[Serializable]System.Exception 然而ISerializable,所以你需要实现序列化构造函数(BlahException (SerializationInfo info, StreamingContext context) 并将参数向下传递给 base()

【讨论】:

以上是关于沙盒 AppDomain 跨程序集异常处理的主要内容,如果未能解决你的问题,请参考以下文章

AppDomain 未处理的异常

AppDomain.UnhandledException 自动重新抛出已处理的异常

Rebus,从异步处理程序创建 AppDomain / Instance 时出现异常

C#、MAF、单独 AppDomain 中的未处理异常管理

是否可以防止子 AppDomain 中的未处理异常导致主进程崩溃?

在沙盒 Appdomain 中加载程序集 - SecurityException