java - 为什么可变字符串会导致安全问题?

标签 java string immutability

看到另一个人的回答post :

字符串已被广泛用作许多 java 类的参数,例如用于打开网络连接,用于打开数据库连接,打开文件。如果 String 不是不可变的,这将导致严重的安全威胁。

我认为在使用前检查字符串可以解决问题。为什么字符串被设计为不可变的原因?

谁能给我一个具体的代码示例?

最佳答案

一般来说,当值不变时,编写和审查敏感代码会更容易,因为 可能影响结果的操作交错更少。

想象一下这样的代码

void doSomethingImportant(String name) {
  if (!isAlphaNumeric(name)) { throw new IllegalArgumentException(); }
  Object o = lookupThingy(name);
  // No chance of SQL-Injection because name is alpha-numeric.
  connection.executeStatement("INSERT INTO MyTable (column) VALUES ('" + name + "')");
}

代码会进行一些检查以防止权限升级,但这仅在调用 executeStatement 的参数时 isAlphaNumeric(name) 为真时才成立。

如果前两个语句被重新排序,那么这将不是问题,所以不安全的部分原因是错误的交错。但是其他代码可能会调用此函数并假定 name 未被它更改,因此可能必须执行并重新执行有效性检查。

如果 String 不是不可变的,那么它可能已被 lookupThingy 更改。为确保安全检查有效,必须正确执行大量代码才能使此代码安全地抵御 SQL 注入(inject)。

不仅必须正确执行的代码量更大,而且对一个功能进行本地更改的维护人员可能会影响远处其他功能的安全性。非局部效应使代码维护变得困难。维护安全属性总是很冒险,因为安全漏洞很少是显而易见的,因此随着时间的推移,可变性会导致安全性下降。


Why is it a reason that string is designed to be immutable?

这与它在安全方面不佳的原因是分开的。

人们普遍认为,使用具有现成的不可变字符串类型的语言编写的程序比不使用的程序执行的不必要的缓冲区复制更少。不必要的缓冲区副本会耗尽内存,导致 GC 搅动,并可能导致对大输入的简单操作比对小输入执行的更差。

人们还普遍认为,使用不可变字符串更容易编写正确的程序,因为您不太可能无法防御性地复制缓冲区。

关于java - 为什么可变字符串会导致安全问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17842911/

相关文章:

java - 是否有用于在 Java 中编码本地时间的类?

java - Hibernate 多态查询

javascript - 在 react 中使用 setState 将预定义对象插入数组

c++ - C++中类字符串的内部结构

C++11 - 区分右值指针

c# - 为什么 IEnumerable<T> 中的元素有时是可变的,有时是不可变的?

c++ - 声明 C++ 不可变类的惯用方式

java - 如何从 Windows git shell/gnu makefile 调用 javac

java - 如何通过按钮和另一个方法调用一个方法

android - 如何在Android中的字符串中插入新行