Java字符串不可变如何提高安全性?

2022-09-02 21:35:31

我刚刚了解到 a 是不可变的。当我阅读它背后的原因时,出现了一些原因,例如性能提高,或者由于它的值无法修改,它可以由多个线程共享。这些原因我都明白。String

但我不明白它与安全性有何关系。不可变性如何帮助 Java 安全性?String


答案 1

编写类库时,一种非常常见的做法是将传递到 API 中的参数存储在构造函数中,如下所示:

public class MyApi {
    final String myUrl;
    public MyApi(String urlString) {
        // Verify that urlString points to an approved server
        if (!checkApprovedUrl(urlString)) throw new IllegalArgumentException();
        myUrl = urlString;
    }
}

如果可变,这将导致一个微妙的漏洞利用:攻击者将传递一个好的URL,等待几微秒,然后将URL设置为指向攻击站点。String

由于在不复制的情况下进行存储是一种相当普遍的做法,并且由于字符串是最常用的数据类型之一,因此使字符串可变会打开许多尚未编写的API,从而导致严重的安全问题。使字符串不可变可关闭所有 API(包括尚未编写的 API)的此特定安全漏洞。


答案 2

不可变的字符串是 SecurityManager 概念正常工作所必需的。dasbklinkenlight已经走上了他的答案,但可变字符串将完全打破沙盒概念。

例如,当您执行读取文件时,API 实现将在内部执行以下操作:new FileInputStream("foo");

  • 调用安全管理器的 checkRead 方法,并将“foo”作为参数,并在检查失败时引发异常
  • 如果安全检查通过,则使用操作系统调用实际打开文件

如果调用程序能够在这两个步骤之间修改字符串,则一个文件的安全检查可能会成功,而实际上将打开另一个文件。