为什么公共静态最终阵列是一个安全漏洞?
有效的java 说:
潜在的安全漏洞!
静态公共最终 Thing[] VALUES = { ... };
有人能告诉我什么是安全漏洞吗?
有效的java 说:
潜在的安全漏洞!
静态公共最终 Thing[] VALUES = { ... };
有人能告诉我什么是安全漏洞吗?
声明字段通常是类常量的标志。它非常适合基元类型(ints,doubles等)和不可变类,如字符串和.对于数组,问题在于即使数组引用是常量,数组的元素仍然可以更改,并且由于它是一个字段,因此更改不受保护,不受控制,并且通常不受欢迎。static final public
java.awt.Color
为了解决这个问题,数组字段的可见性可以限制为私有或包私有,因此在查找可疑修改时需要考虑较小的代码主体。或者,通常更好的是,取消数组,并使用“List”或其他适当的集合类型。通过使用集合,可以控制是否允许更新,因为所有更新都通过方法进行。您可以通过使用 包装集合来阻止更新。但请注意,即使集合是不可变的,您还必须确保存储在其中的类型也是不可变的,否则对假定常量进行未经请求的更改的风险将再次出现。Collections.unmodifiableList()
要了解为什么这是一个潜在的安全漏洞,而不仅仅是封装不良,请考虑以下示例:
public class SafeSites {
// a trusted class with permission to create network connections
public static final String[] ALLOWED_URLS = new String[] {
"http://amazon.com", "http://cnn.com"};
// this method allows untrusted code to connect to allowed sites (only)
public static void doRequest(String url) {
for (String allowed : ALLOWED_URLS) {
if (url.equals(allowed)) {
// send a request ...
}
}
}
}
public class Untrusted {
// An untrusted class that is executed in a security sandbox.
public void naughtyBoy() {
SafeSites.ALLOWED_URLS[0] = "http://myporn.com";
SafeSites.doRequest("http://myporn.com");
}
}
如您所见,错误使用最终数组意味着不受信任的代码可能会破坏受信任的代码/沙盒试图施加的限制。在这种情况下,这显然是一个安全问题。
如果您的代码不是安全关键型应用程序的一部分,则可以忽略此问题。但国际海事组织这是一个坏主意。在将来的某个时候,您(或其他人)可能会在安全性是一个问题的上下文中重用您的代码。无论如何,这就是为什么作者将公共最终数组称为安全问题的原因。
琥珀在评论中这样说:
没有比私人更多的安全漏洞,如果你能以任何一种方式读取源代码和/或字节码......
事实并非如此。
事实上,一个“坏人”可以使用源代码/字节码来确定a存在并引用数组,这一事实不足以破坏安全性。坏人还必须将代码注入到具有使用反射所需权限的JVM中。此权限不适用于在(正确实现的)安全沙箱中运行的不受信任的代码。private