Java 类及其成员的可访问性限制是否是更安全代码的有效实践?

Java 类及其成员的可访问性限制是否是更安全代码的有效实践?,java,security,immutability,secure-coding,Java,Security,Immutability,Secure Coding,根据Oracle安全编码指南指南4-1/EXTEND-1和指南4-5/EXTEND-5 您应该限制类及其成员的可访问性,作为防止攻击者恶意重写的安全控制 为继承设计类和方法或将其声明为最终类和方法。左边 非final,类或方法可以被 攻击者。不允许子类化的类更容易创建 实施并验证它是否安全 在真实场景中,攻击者如何实际利用下面的不安全类进行攻击? 即使类已经加载到正在运行的JVM中,他/她也可以这样做吗 public class PasswordVerifier { private St

根据Oracle安全编码指南指南4-1/EXTEND-1和指南4-5/EXTEND-5 您应该限制类及其成员的可访问性,作为防止攻击者恶意重写的安全控制

为继承设计类和方法或将其声明为最终类和方法。左边 非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作为一个依赖项包括在内,而大多数项目都没有这种依赖项。使用此方法,类是否为final并不重要。从这里,攻击者只需修改
isPasswordValid()
方法即可始终返回true

如果类已经加载,我认为这是不可能的。请参阅此处的更多信息:

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


如果代码被用作库:

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

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

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

EDIT:我忘了提到一些东西在Java的更高版本中可能不起作用,在Java的更高版本中,类操作和依赖项访问受到了更严格的限制。我的所有这些都是基于您使用Java8,大多数人仍然这样做

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

如何
evillipasswordverifier extensed PasswordVerifier{public boolean isPasswordValid(String password){return true;}}
@ElliottFrisch我想OP是在问攻击者在什么情况下可以向应用程序添加新类,而不是他们可能添加什么类型的类。如果你在云中部署代码,然后,攻击者可能会攻击您的主机或虚拟主机,并注入一个如前所述的类。如果代码是库的一部分,那么攻击者只需添加一个类和库即可。如果代码在自己的服务器上运行,那么我同意攻击向量更难。但是你没有告诉我们太多。谢谢你,我一定会尝试ASM和调用API,看看我是否能做到。