如何在不泄露敏感信息的情况下编写例外情况?

时间:2013-12-02 03:21:19

标签: java security sqlexception

从安全的角度来看,我正在编写一个程序,它将捕获一个SQLException。我正试图清除所有敏感信息。

catch(SQLException se){
}
se.printStackTrace();

以上述方式编写会泄露敏感信息吗?如果是这样,那么编写它的安全方法是什么?

4 个答案:

答案 0 :(得分:1)

您正在揭示代码的一部分,因为将打印行号和变量名称。

最好的方法是自定义您自己的消息。另一种方法可能类似于打印IIS错误消息的方式:如果请求来自服务器计算机(调试),则显示完整堆栈跟踪,但显示外部请求的一般错误。

答案 1 :(得分:0)

即使从用户体验的角度来看,喷出技术信息也会给用户带来蹩脚的体验。

使用礼貌的一般错误代码(和/或错误消息),用户可以发送给您以帮助调试

答案 2 :(得分:0)

CERT Secure Coding阐明了这个话题。他们给出了为什么简单地打印堆栈跟踪不安全的例子。从技术和商业角度来看,存在几个问题:

  • SQLExceptions可以显示有关数据库结构的提示
  • 敏感客户信息可以通过例外显示
  • 堆栈跟踪通常可以揭示应用程序的实现细节

您可以采取以下措施来减轻这些风险。

  1. 弃掉例外情况。虽然远非理想,但一个可能的解决方案可能是捕获原始异常,并将无敏感数据的消息打印到标准错误或使用不同的消息抛出新异常。但是,这可能会使调试变得困难,但它可以降低暴露敏感信息的风险。

    catch(SQLException se){
        throw new SQLException("Error executing query.");
    }
    
  2. 清理异常。

    catch (SQLException se) { 
        MyExceptionCleaner.clean(se); // Remove any sensitive data 
    }
    
  3. MyExceptionCleaner对象能够捕获和过滤任何敏感数据,同时仍保留可能对维护有用的任何细节。有关详细信息,请查看this问题。

答案 3 :(得分:0)

问)为什么在抛出异常后打印堆栈跟踪是不安全的?

A)堆栈跟踪是一个信息泄漏,它揭示了有关系统实现的一些细节。这不是一个严重的漏洞,但可以帮助攻击者获取有关数据库设计的某些信息(数据库版本,表名,代码文件名)。

打印堆栈跟踪还可能允许攻击者使用调试工具来识别和利用系统中的漏洞。

除了上面讨论的安全问题之外,不应该向系统的任何用户或攻击者显示堆栈跟踪。 如果将诸如堆栈跟踪之类的错误打印到控制台上,则会降低客户对系统的信心。

用户不清楚他们的交易是否已经完成,或者不清楚为什么会出现这样的错误。

发生错误 摘要: 查询表达式中的语法错误(缺少运算符)' username =' john'或1 = 1'和密码=' gggg''。 错误信息: System.Data.OleDb.OleDbException:查询表达式中的语法错误(缺少运算符)' username =' john'或1 = 1' 和密码=' gggg''。 在System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams,Object& executeResult)at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& executeResult)at at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior,Object& executeResult)at at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior,String method)at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)at System.Data.OleDb.OleDbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)at at System.Data.Common.DbDataAdapter.FillInternal(DataSet数据集,DataTable [] datatables,Int32 startRecord,Int32 最大记录, 字符串srcTable,IDbCommand命令,CommandBehavior行为)at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet,Int32 startRecord,Int32 maxRecords,String srcTable, IDbCommand命令, System.Data.Common.DbDataAdapter.Fill(DataSet dataSet,String srcTable)at的CommandBehavior行为 Altoro.Authentication.ValidateUser (String uName,String pWord)位于c:\ downloads \ AltoroMutual_v6 \ website \ bank \ login.aspx.cs:第68行at at Altoro.Authentication.Page_Load(Object sender,EventArgs e)位于c:\ downloads \ AltoroMutual_v6 \ website \ bank \ login.aspx.cs:第33行 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,Object o,Object t,EventArgs e)at at System.Web.UI.Control.OnLoad中的System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender,EventArgs e) (EventArgs e)at System.Web.UI.Page.ProcessRequestMain中的System.Web.UI.Control.LoadRecursive()(布尔值 includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)

如上面显示的示例堆栈跟踪所示,输入的用户名包含不希望输入用户名字段的无效字符,因此系统崩溃并将此详细堆栈跟踪抛出到屏幕。

应该发生的事情是由开发人员抛出的自定义异常,而不是向用户显示所有上述敏感信息,只显示如下消息:

    Invalid character entered.
    Please enter letters only.
    Please try again!

处理异常和堆栈跟踪的两种方法是 SANITIZING PURGING。

1)消毒

如上所示,开发人员预计输入中可能会出现错误,并编写了一个代码的错误处理部分,而不是打印堆栈跟踪,向用户打印了一条易于理解的消息,说明他们的操作未完成的原因。

开发人员清理或清洁"防止中止的例外 系统崩溃并且可以添加循环,因此如果输入的数据不正确,将抛出错误消息,并且用户要求重新输入其凭据。

2)清除

与清理类似,发生错误的预期允许开发人员干预并显示仅为了解开发人员而定制的错误消息,或者可能根本不会抛出错误,只会出现自定义错误抛出到日志文件。

任何面临发生错误的用户都将进行清理,以便客户可以轻松了解错误发生的原因并记录错误。已记录的错误将在日志文件中清除,并带有ID号或自定义

抛出错误,而不是显示 FileNotFoundException 在日志中,开发人员可以自定义该内容以阅读错误:782

这可以防止以纯文本形式显示描述性错误,显示系统中的漏洞。错误的自定义ID记录在公司数据库中的错误字典中,以便开发人员可以搜索ID并将描述分配给错误,以了解它为何发生,但只有授权用户可以访问它,防止滥用信息。