是否有必要将每个异常都包装在顶级
本文关键字:包装 异常 是否 | 更新日期: 2023-09-27 18:25:19
今天,有人告诉我,我们应该始终在框架的顶层包装每个异常。原因是原始异常可能在堆栈跟踪或消息中包含敏感信息,尤其是堆栈跟踪。
我不知道,有什么规则/原则/模式吗?
今天,有人告诉我,我们应该始终将每个异常都封装在框架的顶层。
"总是"似乎有点过分。
像任何其他设计决策一样,您应该考虑成本和收益。
因为原始异常可能在堆栈或消息中包含敏感信息,尤其是堆栈。
的确;异常可能包含敏感信息,攻击者可能会使用堆栈跟踪。
有什么规则/原则/模式吗?
是的。在做任何事情之前,特别是在进行设计或代码更改之前,创建一个威胁模型。您提出了一个安全问题,因此,在制定一个好的策略来缓解漏洞之前,您必须完全了解威胁。
您的威胁模型回答的核心问题应该是"我的应用程序的信任边界是什么?数据何时以及如何跨越边界?这会暴露出什么漏洞?攻击者可以因此弥补哪些威胁?"
如果你不清楚信任边界、漏洞、威胁和攻击者是什么,那么在你试图设计一个安全系统来减轻威胁的漏洞之前,先了解这些词的含义。"编写安全代码2"是一个很好的起点。(在我关于代码安全的书的第5章中,有一些关于消除异常漏洞的好建议,但它已经绝版很久了。也许有一天我会把它放在博客上。)
数据可以在任一方向跨越信任边界;不受信任的客户端可能正在向您的服务器发送格式错误的数据,而您的服务器可能正在向不值得信任的客户端发送敏感的私人数据。
您的问题具体涉及的威胁模型的特定方面是异常形式的数据。我不骗你,在我们发货之前。NET 1.0中,您实际上可以让框架给您一个异常,其文本类似于"您没有权限确定目录C:''foo的名称"。(太好了。谢谢你让我知道。我现在肯定不会使用这些信息攻击用户。)
很明显,这个问题早在我们发货之前就解决了,但人们每天都在做同样的道德行为。如果你的数据跨越了信任边界,你应该假设不受信任方的敌对用户会试图在受信任方引发异常,并试图从这些异常中尽可能多地了解系统不要让攻击者的工作更轻松
您询问是否应该包装所有异常。大概如果事实上你有一个问题——如果包含敏感数据的异常可以跨越信任边界,那么包装异常可能是正确的做法。但可能这还不够。也许您根本不需要跨越边界抛出异常,即使可以对异常进行santization。也许正确的做法是进入全红警报,并说"嘿,我们收到了一个由潜在敌对第三方的坏数据引起的意外异常,所以让我们(1)禁止他们的IP,或(2)将他们重定向到蜜罐服务器,或(3)警告安全部门,或(4)其他什么。"什么是正确的解决方案取决于威胁,你还没有说明。
正如我所说的,您需要做的第一件事就是模拟威胁。不要在没有彻底了解威胁的情况下就做出安全决策。
是的,有一条规则:这是愚蠢的。
我们需要了解更多细节,但最后:
-
您可以也应该有一个用于异常的顶级处理程序。这不在您的框架中(即包装顶层),而是附加到appdomain(未处理的异常)。这允许您显示错误消息并写入日志等。
-
最后,您应该传播尽可能多的信息。规则是"抓住你能处理的,抓住你不能处理的"。
-
现在它变得有趣了。"敏感信息"是指"调试所使用和需要的信息"。顶级标准说"包装异常=原始异常进入内部异常属性"。
框架不应向用户公开敏感信息,但这是特定于应用程序的(iis:自定义错误页、windowms等:最后的处理程序,不会向用户显示太多详细信息,因为用户无论如何都不在乎)。
在正常情况下为用户显示堆栈跟踪不是最好的主意。我使用设置为"true"的DEBUG常量进行调试和开发,在正常情况下设置为"false",看看这个PHP示例
DEFINE("DEBUG" true);
function soap_error($soapFault)
{
if (DEBUG)
{
// full message with stack including sensitive info
echo '<p class="error">SOAP error:</p><br />';
echo '<p>'.$soapFault.'</p><br />';
echo '<hr />';
}
else
{
// only error message
echo '<p class="error">SOAP error:</p><br />';
echo '<p>'.$soapFault->getMessage().'</p><br />';
echo '<hr />';
}
}
您也可以使用日志文件来保存完整的错误堆栈。
在C#/.NET中,这更容易,因为您在Visual Studio中有构建配置,您可以在它们之间切换并使用类似的东西:
public static void myerrorhandler(Exeption e)
{
#if (DEBUG) // you have DEBUG and RELEASE configurations by default
yourErrorMessageFunction("This is error message and stack " + e.toString());
#else
yourErrorMessageFunction("This is only message" + e.Message());
#endif
}
Visual Studio正在添加和控制DEBUG常量(它在"构建配置"中设置,您可以在那里自定义它)。