限制类及其成员的可访问性是否是更安全代码的有效做法



根据Oracle安全编码指南指南4-1/EEXTEND-1和指南4-5/EEXTEND-5您应该限制类及其成员的可访问性,以防攻击者恶意覆盖。

为继承设计类和方法,或将它们声明为final。左边非final,类或方法可能被攻击者。不允许子类化的类更容易实现并验证它是否安全。

在现实世界中,攻击者如何真正利用以下不安全类?即使类已经加载到正在运行的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;
}
}

如果我们谈论的是一个可以访问源代码的恶意内部人员,难道他一开始就不能删除最后一个修饰符(如果已经有(或通过任何方式更改类本身吗?

无论是否有final关键字,该代码都是不安全的。它还很大程度上取决于它运行的环境

如果JVM已经在运行:

要困难得多。我确实注意到了通过C++进行注入的一些事情,这可能为在加载类时使用ASM生成/修改运行时类开辟了可能性。这需要将ASM作为依赖项包括在内,而大多数项目都没有这种依赖项。使用此方法,类是否为最终类都无关紧要。从那里,攻击者可以修改isPasswordValid()方法,使其始终返回true。

如果该类已经加载,我认为这是不可能的。点击此处查看更多信息:

C++在运行的JVM 中调用函数

调用API

我想在运行时更改已经加载的java类。如何做到这一点?

这也提供了一个有趣的阅读:

Java中是否可以进行代码注入?


如果代码被用作库:

容易多了。攻击者可以像您所说的那样删除final修饰符,也可以使用类似ASM的东西生成一个最初没有final修饰符的新类。也可以只使用sun.misc.Unsafe,如这里的repo所示。这将允许他们生成一个新的类,扩展不再是最终类的类。

另一种方法是在加载时只使用ASM来修改类,这会更容易。

可能有更多的方法可以做到这一点,我自己也没有测试过其中的任何一种,但我认为这两种情况都有可能,这取决于环境。

EDIT:我忘了提到,这些东西中的一些可能在Java的后续版本中不起作用,因为在Java的后期版本中,类操作和依赖项访问受到了更大的限制。我把所有这些都建立在你使用Java8的基础上,大多数人仍然这样做

EDIT2:我刚刚在这里找到了这篇文章,它提供了一种通过调试模式执行任意代码的方法,也可以用来操作类。链接

相关内容

  • 没有找到相关文章

最新更新