内存堆安全性:字符串垃圾收集

我最近一直在为我的公司进行安全代码审查,并使用名为Fortify360的工具。 它将识别代码的许多问题并描述问题。 它提出的一个有趣的问题是我没有找到任何其他信息如下:

“存储在内存中的敏感数据(如密码)如果存储在托管的String对象中,可能会泄露。字符串对象没有固定,因此垃圾收集器可以随意重定位这些对象,并在内存中留下几个副本。这些对象是默认情况下没有加密,所以任何能够读取进程内存的人都能看到内容。此外,如果进程’内存被换出到磁盘,则字符串的未加密内容将被写入交换文件。 ,因为String对象是不可变的,所以只能通过CLR垃圾收集器从内存中删除String的值。除非CLR内存不足,否则不需要运行垃圾收集器,因此不能保证何时垃圾将发生收集。如果应用程序崩溃,应用程序的内存转储可能会泄露敏感数据。“

所有这些我理解为很有道理,而且我对这个问题的研究非常标准。

问题是:我该如何解决这个问题? 假设有问题的类不能从iDisposableinheritance(非常大的应用程序,并且在所讨论的字符串之后很久就需要该类)。 是否有另一种手动内存管理方式来处理特定字符串而不调用垃圾收集器,GC.Collect()??

提前感谢您的帮助。

亚历克斯

如果你想避免这种情况,你需要使用IDisposable System.SecureString来保存敏感数据,只保留所需的最短时间。

具有讽刺意味的是,MSDN示例代码不会显式地或using封装来Dispose实例。

老实说,解决这个“问题”将比它的价值更麻烦。

使用ASP.NET等技术时,无法阻止用户提交密码,除非您在发送之前在客户端加密字符串,因为ASP.NET会将它们存储为表单集合中的字符串等。

如果您确实使用了JS加密路由,请注意任何潜在的攻击者也能够解密他从您的应用程序中恢复的字符串。

但是,如果有人闯入了Web服务器,那么他可能会破坏整个数据库。 这比从Web服务器堆中收集一些密码要严重得多……

现在,如果这不是ASP.NET应用程序,并且您可以完全控制如何在代码中处理密码,那么您可以查看SecureString 。 但是您仍然可以发现最小的好处超过了代码复杂性的增加。 这实际上取决于密码泄漏的严重程度,以及您的机器首先受到损害的程度。 如果您不担心某些远程攻击者能够调试您的进程并获取内存快照,那么这实际上不是问题。

总结:如果攻击者有能力从内存或交换中提取这些字符串, 他也有能力做更糟糕的事情