在Java中,如何从HttpServletRequest头提取密码而不生成String对象?
处理敏感数据(=密码)的通用Java安全指南建议永远不要使用字符串对象来存储数据,而是使用字节或字符数组。我正试图在HttpServlet处理程序中应用此准则。特别是,我使用的是一种基本的类似身份验证的方法,其中凭据在头中传递(这是一个GET请求,因此没有正文) 我遇到的问题是,在不生成String对象的情况下,似乎不可能获取标题数据,这违反了get go的指导原则。我已经非常彻底地寻找了解决方案,但没有找到任何相关的讨论。有人对这个问题有什么见解吗在Java中,如何从HttpServletRequest头提取密码而不生成String对象?,java,security,servlets,passwords,http-headers,Java,Security,Servlets,Passwords,Http Headers,处理敏感数据(=密码)的通用Java安全指南建议永远不要使用字符串对象来存储数据,而是使用字节或字符数组。我正试图在HttpServlet处理程序中应用此准则。特别是,我使用的是一种基本的类似身份验证的方法,其中凭据在头中传递(这是一个GET请求,因此没有正文) 我遇到的问题是,在不生成String对象的情况下,似乎不可能获取标题数据,这违反了get go的指导原则。我已经非常彻底地寻找了解决方案,但没有找到任何相关的讨论。有人对这个问题有什么见解吗 注意:这是通过HTTPS实现的,因此这里没有
注意:这是通过HTTPS实现的,因此这里没有连接安全问题。简单的答案是,除了字符串之外,您无法以任何其他形式获取参数。至少,不使用标准servlet API。但也有一些可能的“脱身”
话虽如此,IMO对Java安全性的“无条件”方法是错误的,或者至少在实现方面被高估了 “无字符串”方法可以防止某些东西可能会在应用程序的地址空间中搜索,找到看起来像字符串的东西,并嗅出可能的密码。理论上,这可以通过以下方式实现:
- 破坏JVM执行模型并查看原始内存的黑客行为
- 附加Java调试器并遍历可访问对象
- 使用“/dev/mem”或类似工具从外部读取进程内存
- 访问硬盘上程序交换映像的剩余部分,或
- 以某种方式使其核心转储并读取转储
总之,“无条件”可以防止真正困难的黑客攻击,或者防止您的安全性已经被破坏的情况。依我看,这是不值得的努力。。。除非你被要求实现军事级安全。@smk:因为
String
s可以被拘留,这意味着它们在你使用完之后很长时间都会留在内存中。@smk字符串是不可变的。一旦你有了一个,它就会一直挂在内存中,直到它被垃圾回收(在你处理完之后很久)。使用字节[]
,一旦使用完毕,就可以覆盖内容以防止数据被读取。@CameronSkinner这与实习无关(尽管这会加剧问题)。即使堆空间中尚未被垃圾收集的字符串在内存中仍然是不可变的。也许这种担心在客户端机器上有一定的有效性,但在服务器机器上却没有,因为服务器机器上有很多更重要的秘密可以轻易地访问。请参阅#1,Java是否定义了可能发生的后果?假设内存中某处已经存在一个相等的字符串,例如哈希表中的一个键。在这种情况下,Java实现是否允许将两个字符串映射到同一个“文本备份存储”(抱歉,我不知道这里的确切Java术语)?如果是这样的话,通过明确清除HTTP数据包中的字符串,我实际上可能在我的应用程序中打开了一个恶意的DOS安全漏洞,它可以做到这一点。但实际上,只有在两个字符串上都调用String.intern()
时,它才会这样做。另一种可能性是密码字符串与较大的字符串共享支持;e、 g.表示标题行的字符串。我认为这两种情况都不会有问题。实际上,还有另一种情况。这是较旧的JVM,String
的实现在某些情况下会在不同的字符串之间共享char[]
后备数组。字符串的实现在Java1.7.0_6中被重写以解决这个问题。(这是内存泄漏的来源!)