根据Oracle安全编码准则4-1/扩展-1和准则4-5/扩展-5,您应该限制类及其成员的可访问性,作为抵御攻击者恶意覆盖的安全控制。
为继承设计类和方法,或将它们声明为最终。一个类或一个方法可能被攻击者恶意覆盖.不允许子类的类更容易实现和验证它是否安全。
在实际场景中,攻击者如何实际利用下面的不安全类?即使类已经加载到正在运行的JVM中,他/她也能这样做吗?
public class PasswordVerifier {
private String regex;
public PasswordVerifier(String regex) {
this.regex = regex;
}
public boolean isPasswordValid(String password) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(password);
return matcher.find();
}
public String getRegex() {
return regex;
}
public void setRegex(String regex) {
this.regex = regex;
}
}如果我们说的是一个恶意的内部人员,他有权访问源代码,他就不能直接删除最后一个修饰符(如果已经有一个修饰符),或者从一开始就改变类本身吗?
发布于 2020-09-20 20:58:47
无论是否存在final关键字,该代码都不安全。它也很大程度上取决于它所处的环境。
如果JVM已经在运行,则为:
要难得多。我确实注意到了通过C++进行注入的一些事情,这可能会在类加载时使用ASM来生成/修改运行时类。这将要求ASM作为一个依赖项被包括在内,而大多数项目都没有这种依赖。使用这种方法,类是否是最终类并不重要。然后,攻击者只需修改isPasswordValid()方法就可以始终返回true。
如果类已经加载,我认为这是不可能的。在这里见更多:
这也提供了一个有趣的阅读:
如果代码被用作库,则为:
容易多了。攻击者可以像您所说的那样移除final修饰符,或者生成一个新的类,该类最初没有final修饰符。您也可以使用sun.misc.Unsafe,如这个回购这里所示。这将允许他们生成一个新的类,扩展不再是最终类的类。
另一种方法是在类加载时使用ASM来修改类,这样会更容易。
可能有更多的方法,而且我自己也没有实际测试过其中的任何一个,但我认为这在这两种情况下都是可能的,这取决于环境。
编辑:--我忘了提到,其中一些东西在后期版本的Java中可能不起作用,那里的类操作和依赖关系访问受到更多的限制。我所有这些都是以Java 8为基础的,大多数人都是这样做的。
编辑2: --我刚刚在这里找到了本文,它提供了一种通过调试模式执行任意代码的方法,该方法也可以用来操纵类。链接
https://stackoverflow.com/questions/63983042
复制相似问题