Java 不可修改集合中的静态场初始化
我有一个静态字段,它由静态块中的config属性初始化。我的代码将针对Fingbugs警告运行,该警告遇到如下所述的警告 字段是一个可变集合 可变集合实例被分配给最终的静态字段,因此可能会被恶意代码或来自另一个包的意外更改。考虑将此字段打包为CopysNunMudiabLeSt/List/MAP/ETC。以避免此漏洞。Java 不可修改集合中的静态场初始化,java,findbugs,Java,Findbugs,我有一个静态字段,它由静态块中的config属性初始化。我的代码将针对Fingbugs警告运行,该警告遇到如下所述的警告 字段是一个可变集合 可变集合实例被分配给最终的静态字段,因此可能会被恶意代码或来自另一个包的意外更改。考虑将此字段打包为CopysNunMudiabLeSt/List/MAP/ETC。以避免此漏洞。 我如何才能将其设置为未修改集,并在以后的阶段将其作为字符串文本传递?我认为这是Findbugs中的一个错误。现在尝试将该字段标记为private,也许这有助于解决此问题。如果这无
我如何才能将其设置为未修改集,并在以后的阶段将其作为字符串文本传递?我认为这是Findbugs中的一个错误。现在尝试将该字段标记为private,也许这有助于解决此问题。如果这无助于修复它,我的直觉是它是一个错误只是有点大 可以看出,异常有些不正常,因为它不是一个集合,并且不能在此类之外进行任何更改,因为它具有
private
access修饰符,并且它是一个字符串,在Java中本质上是不可变的
让我们看看这个例子
public class Class1 {
private static String STRING_VALUE = "I'm secure!";
private static List<String> COLLECTION = Arrays.asList("I'm Secure!");
public static void main(String[] args) {
Class2.changeStatic(STRING_VALUE);
System.out.println(STRING_VALUE); // I'm secure!
Class2.changeStatic(COLLECTION);
System.out.println(COLLECTION.get(0)); // I'm unsecure!
}
}
public class Class2 {
public static void changeStatic(String secureString) {
secureString = "I'm unsecure!";
}
public static void changeStatic(List<String> unsecureList) {
unsecureList.set(0, "I'm unsecure!");
}
}
公共类1{
私有静态字符串_VALUE=“我很安全!”;
private static List COLLECTION=Arrays.asList(“我很安全!”);
公共静态void main(字符串[]args){
类别2.changeStatic(字符串值);
System.out.println(STRING_VALUE);//我很安全!
类别2.变更静态(集合);
System.out.println(COLLECTION.get(0));//我不安全!
}
}
公共课2{
公共静态void changeStatic(字符串secureString){
secureString=“我不安全!”;
}
公共静态void changeStatic(列表未固化列表){
未治愈列表。设置(0,“我未治愈!”);
}
}
正如您所看到的,在类本身之外,无法更改Class1的字符串值。对于集合,这是可能的,因为元素保存在可变容器中
由于可以在类/包之外更改集合中的元素,因此他们建议将其包装在不可修改的集合中,该集合不会将修改委托给包装列表,而是引发异常:
public class Class1 {
private static List<String> COLLECTION = Collections.unmodifiableList(Arrays.asList("I'm Secure!"));
public static void main(String[] args) {
Class2.changeStatic(COLLECTION);
}
}
public class Class2 {
public static void changeStatic(List<String> unsecureList) {
unsecureList.set(0, "I'm unsecure!"); // throws a java.lang.UnsupportedOperationException
}
}
公共类1{
private static List COLLECTION=Collections.unmodifiableList(Arrays.asList(“我很安全!”);
公共静态void main(字符串[]args){
类别2.变更静态(集合);
}
}
公共课2{
公共静态void changeStatic(列表未固化列表){
set(0,“我不安全!”;//抛出java.lang.UnsupportedOperationException
}
}
当您将字段标记为final时,是否仍然存在错误?是否尝试了私有静态final URI=Properties.getProperty()
?这应该是@ÉricRoberge的作品,在这次修改后仍然看到同样的问题。你在代码的其他地方使用静态集合吗?它不是Findbugs中的bug。@LewBloch你怎么确定这一点?你能详细说明一下吗?我明显没有注意到的安全风险在哪里?发现Bugs已经存在了十多年了。从二阶近似来看,它从来都不是工具。风险在于,客户机可能会修改集合,程序员可能会误解final
。OP讨论了集合
,他们发布的代码是不可编译的,并且没有显示集合
。我的结论是,发布的代码不是Findbugs分析的代码。如果OP在实际代码中设置了一个,而他们没有显示给我们,那么该消息是合法的。是的,他总是有可能误解了警告的位置。我们不能肯定。而每一个软件,不管有多旧,都可能包含某些怪癖。我不使用Findbugs,因此很遗憾,我无法验证指定的行为。
public class Class1 {
private static List<String> COLLECTION = Collections.unmodifiableList(Arrays.asList("I'm Secure!"));
public static void main(String[] args) {
Class2.changeStatic(COLLECTION);
}
}
public class Class2 {
public static void changeStatic(List<String> unsecureList) {
unsecureList.set(0, "I'm unsecure!"); // throws a java.lang.UnsupportedOperationException
}
}