在Java中,如何在不生成String对象的情况下从HttpServletRequest标头中提取密码?

用于处理敏感数据(== 密码)的常见 Java 安全准则建议从不使用 String 对象来存储数据,而是使用字节或字符数组。我正在尝试在HttpServlet处理程序中应用此准则。特别是,我使用类似基本身份验证的方法,其中凭据在标头中传递(这是一个GET请求,因此没有正文)。

我遇到的问题是,如果不生成 String 对象,似乎就不可能访问标头数据,这从一开始就违反了该准则。我已经非常彻底地搜索了解决方案,但没有找到任何相关的讨论。有人对这个问题有任何见解吗?

注意:这是通过HTTPS进行的,因此这里没有连接安全问题。


答案 1

简单的答案是,除了 String 之外,您无法以任何其他形式获取参数。至少,不使用标准的 Servlet API。但是有几种可能的“脱身”。

  1. 如果你准备变得非常丑陋,你实际上可以打破String对象的抽象,并伸入并覆盖字符。(如果您准备打破规则,字符串实际上是可变的。这是少数几种可能证明合理的情况之一。

  2. Web 容器的实现中可能存在非标准 API 扩展(比如说)用于执行此操作。如果没有,您可以掌握源代码并添加一个。(假设您使用的是开源 Web 容器。HttpServletRequest


话虽如此,IMO对Java安全性的“无条件”方法被误导了,或者至少在它所实现的目标方面被高估了。

“无字符串”方法可防止某些内容在应用程序的地址空间中拖网,找到看起来像字符串的内容,并嗅出可能的密码。从理论上讲,这可以通过以下方式完成:

  • 一个破解JVM执行模型并查看原始内存的黑客,
  • 附加 Java 调试器并搜索可访问的对象,
  • 使用“/dev/mem”或类似的东西从外部读取进程内存,
  • 访问硬盘驱动器上程序交换映像的残骸,或
  • 以某种方式导致它核心转储并读取转储。

但是,除了第一个之外,所有这些都要求坏人已经破坏了系统的安全性。如果坏人已经这样做了,还有其他(可能更简单的)方法可以从您的程序中窃取密码...“无条件”方法无法阻止。

如果您担心黑客利用Java安全漏洞来读取原始内存,则该漏洞可能会以其他方式使用;例如,注入代码以改变代码处理密码的方式。

因此,总而言之,“无条件”可以防止非常困难的黑客攻击,也可以防止安全性已经受到打击的情况。IMO,不值得付出努力...除非您需要实施军用级安全性。


答案 2