如何避免在需要使用String的第三方库中存储密码或机密信息?

huangapple go评论66阅读模式
英文:

How to avoid using String for passwords or secrets with 3rd party libraries that require a String?

问题

我正在处理一个Java服务,其中有一个安全漏洞的记录,涉及存储在Java String对象中的密钥。

有关问题是,一旦密码存储在String中,它会留在字符串池中,直到被垃圾回收,并可能在转储中显示为明文。

我理解Java的String类是不可变的,并且最好将秘密或密码存储在可变类中,以便在使用后尽快从内存中删除。

参考资料

然而,当与第三方库一起使用时,我发现这在实际操作中并不切实际,因为许多第三方库希望密码或密钥以String对象的形式传递,无论我在代码中多么安全,最终都会将char[]数组转换为String,这又带回了最初的问题,不是吗?

那么,有没有办法将char[]StringBuffer转换为String,而不回到最初的问题?

编辑:正如在这个问题及其他类似问题的评论中指出的那样,许多人认为这并非真正的问题,因为如果您不拥有应用程序中的所有代码(即不要将秘密传递给任何第三方库),则很难避免此问题。因此,鉴于此,问题可能变成

我如何反驳这个漏洞?有没有来自Oracle/Owasp或其他方面的良好可靠的参考资料,表明这是一个“无法解决的问题”?

英文:

I'm working on a Java service that had a security bug logged against it, concerning a secret stored in a Java String object.

The concern is that once a password is stored in a String, it stays in the string pool until it's garbage collected, and could show up in a dump as clear text.

I understand that Java's String class is immutable, and it is preferred that secrets or passwords be stored in a mutable class, so it can be removed from memory as soon as possible after use.

References

However, I find this impractical when working with 3rd party libraries, as many of them want the password or secret passed in the request as a String object, which no matter how safe I am, in my code, ultimately converts the char[] array into a String, which takes us back to the original problem, doesn't it?

So, is there anyway to convert a char[], or StringBuffer to a String, without getting back to the original problem?

EDIT: As pointed out by the comments in this question and other similar questions, many believe this is not a real concern, as there's no easy way to avoid the issue if you don't own ALL the code in your application (ie don't pass secrets to any 3rd party libraries). So given this, maybe the question becomes

How can I refute the bug? is there a good solid reference from Oracle/Owasp or whoever that says "unsolvable problem" ?

答案1

得分: 5

无法避免创建String,如果需要调用需要String的API。只要避免使用字符串文字或明确内部化的字符串,字符串就不会出现在字符串池中。

这也是一个无法解决的问题。例如,如果这是数据库连接池的密码,密码需要在程序的生命周期内可用,以便能够创建新连接。即使你可以以可清除的方式提供密码,比如char[]CharBufferStringBuilder等,也不能保证你调用的API不会将其转换为字符串,或者进行复制等等。

甚至使用char[]也不能保证你能够正确地将其从内存中清除:Java垃圾收集器可以移动对象,所以很可能你的密码仍然存在于内存的先前位置,即使你明确将那个char[]置零。

如果威胁行为者具有足够的访问权限来检查内存、生成堆转储等,你将面临更大的问题,担心使用Stringchar[]之间的区别只是浪费时间,因为威胁行为者将有其他方法找到你的密码,比如查找配置源,修改程序以在下次运行时记录密码等。

需要明确的是,能够快速清除某些敏感信息可以减少攻击窗口,但除非你在高安全性环境中工作,否则在考虑所有注意事项的情况下,这不太可能是你应该关注的正确事情。

英文:

You can't avoid creating a String if you need to call an API that requires a String. As long as you avoid string literals or explicitly interned strings, strings don't end up in the string pool.

This is also an impossible problem to solve. For example, if this is a password for a database connection pool, the password needs to be available for the lifetime of the program to be able to create new connections. And even if you could provide the password in some clearable way like a char[], CharBuffer, StringBuilder, etc., there is no guarantee that the API you're calling doesn't transform it to a string, or makes a copy, etc., etc.

Even using a char[] does not guarantee that you're able to correctly purge it from memory: Java garbage collectors can and will move objects around, so it is entirely possible that your password is still in memory at a previous location, even if you explicitly zeroed that char[].

If a threat actor has sufficient access to your system to inspect memory, make heapdumps, etc., you have bigger problems, and worrying about using a String vs char[] is just a waste of time, because that threat actor will have other means of finding your password, like finding configuration sources, modifying your program to record the password on a next run, etc.

To be clear, being able to quickly clear certain sensitive information can reduce the window of attack, but unless you're working in high-security environments, it is unlikely to be the right thing to focus on given all the caveats.

huangapple
  • 本文由 发表于 2023年5月10日 23:28:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76220222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定