2012-02-20 18 views
3

今天,有人告诉我,我们应该总是把每个异常都包装在框架的顶层。 原因是原始异常可能包含堆栈跟踪或消息中的敏感信息,特别是堆栈跟踪。是否有必要在顶层包装每个异常?

我不知道,没有任何规则/原则/模式?

+1

看到这个答案:http://stackoverflow.com/a/2737337/368070它适用于一般的异常处理也看到http://stackoverflow.com/questions/881473/why-catch-and。 -rethrow-异常在-C – gideon 2012-02-20 07:59:45

+1

假设整个框架是用C#,任何人都可以反编译,并查看任何一个异常等等。如果你正在寻找隐藏“敏感信息”,可以考虑混淆暴露的方法/消息要么用C++编写处理敏感信息的框架部分,并使用PInvoke进行互操作。 – 2012-02-20 08:02:26

+1

@RobertRouhani:若该方法是在服务器上,攻击者在客户端上。 – 2012-02-20 16:49:19

回答

15

今天,有人告诉我,我们应该总是将每个异常都包装在框架的顶层。

“始终” 似乎有点多。

像任何其他的设计决策,就应该考虑成本和效益。

由于原始异常可能包含在堆栈跟踪或消息的敏感信息,尤其是堆栈跟踪。

确实;该例外可能包含敏感信息,并且攻击者可以使用堆栈跟踪。

是否有任何规则/原则/模式?

是的。在你做之前什么东西别的,特别是在你进行设计或代码更改之前,会制作威胁模型。您正在问一个安全问题,因此您必须首先了解威胁,然后才能制定一个减轻漏洞的好策略。

你的威胁模型回答的核心问题应该是“哪些信任边界我的应用程序?当和如何数据跨界?这是否暴露出什么弱点?什么威胁可能的攻击者的make良好的结果?

如果你不准确地理解什么信任边界,漏洞,威胁和攻击者,然后了解这些词的意思,你尝试设计一个安全系统,以减少漏洞前威胁。 “编写安全代码2”是一个很好的开始。 (我的关于代码安全性的书的第5章在消除异常漏洞方面有一些很好的建议,但它已经很长时间了,可能我会在博客上这么一天。)

数据可以跨越信任边界在任一方向;不受信任的客户端可能会向您的服务器发送格式错误的数据,并且您的服务器可能会将敏感的私人数据发送给不可信的客户端。

您的问题特别提到的威胁模型的特定方面是异常形式的数据。在我们发布.NET 1.0之前,我没有嘲笑你,你实际上可以让框架给你一个例外,其文本类似于“你没有权限确定目录C:\ foo的名字”。 (很好,谢谢你让我知道,我一定不会使用这些信息来攻击用户)

很明显,在我们发货之前很久就已经修好了,但是人们每天都会这样做。如果数据跨越信任边界,则应该假设不信任端的恶意用户将尝试引发可信端的异常,并尝试从这些异常中尽可能多地了解系统。 不要让攻击者的工作更轻松。

你问是否所有例外都应该被包装。也许。如果实际上您遇到了问题 - 如果包含敏感数据的异常可以跨越信任边界,那么也许包装异常是正确的做法。但也许它不是足够。也许你不需要在边界上抛出一个异常,即使这个异常是可以被处理的。或许正确的做法是发出全红警报,并说“嗨,我们因潜在的敌对第三方的不良数据而导致意外异常,所以让我们(1)禁止他们的IP,或者(2)将它们重定向到蜜罐服务器,或(3)警告安全部门,或(4)其他事情。“什么是正确的解决方案是依赖于威胁,你还没有说。

就像我说的,你需要做的是威胁建模。别做安全决策,而不了解的第一件事。彻底的威胁

0

是的,有一条规则:这是愚蠢的。

我们需要知道更多的细节,但在最后:

  • 你可以和应该有例外的顶级处理器。这不在你的框架中(即包装顶层),而是附加到appdomain(未处理的异常)。这使您可以显示错误信息并写入日志等

  • 在您应该传播尽可能多的信息可能结束。规则是“抓住你能处理的东西,不要传播你的东西”。

  • 现在它变得有趣。 “敏感信息”是“信息有用且需要调试”。根据最高标准,“包装例外=原件进入内部例外属性”。

该框架不应该暴露敏感infrmation给用户,但这是特定应用(IIS:自定义错误页,windowms等:最后的处理程序,不显示用户过多的细节,因为用户不无论如何关心)。

+3

保护用户免受攻击者不是“愚蠢的”。 – 2012-02-20 16:30:09

+0

不,但是捕获所有事件并且不提供调试信息。我不能在我的桌子上设想一个软件,只要确保我没有信息来调试它是有帮助的。这个需求听起来很愚蠢。 – TomTom 2012-02-20 17:22:08

-2

用户在正常情况下显示的堆栈跟踪是不是最好的主意。 即时通讯使用DEBUG常数设置为“真”的调试和开发,并在正常情况下设置为“假”,看那个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常数(其在“构建配置”中设置,您可以在其中进行自定义)。

+0

-1,因为(一)psoer不说这是IIS和(b)你猜怎么着 - IIS有一个配置级别的机制,所以它是完全unnnecessary使用定义和(c)你甚至不举一个例子与语言有关。所以,也是错误的答案和错误。 – TomTom 2012-02-20 08:06:20

+0

我在C#.NET中添加了更好的示例。 – Kamil 2012-02-20 08:10:20

+0

-1又因为如果你谈论的是ASP.NET,然后按[ASP.NET健康监测(http://msdn.microsoft.com/en-us/library/bb398933.aspx)将做的工作适合你没有代码。 – 2012-03-02 02:26:49

0

埃里克利珀特写了一个伟大的博客,了解什么样的例外应该抓到哪里。

Vexing exceptions

它不直接回答你的问题,但它提供了有关常规异常处理是个好主意。

相关问题