微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决限制类及其成员的可访问性是否是获得更安全代码的有效做法?

根据 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的运行时类生成/修改之类的事情打开可能性。这将要求将ASM作为依赖项包括在内,而大多数项目则没有。使用此方法,该类是否为final无关紧要。攻击者可以从那里修改isPasswordValid()方法以始终返回true。

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

C++ Call a function inside a running JVM

The Invocation API

I want to change java class at run time which is already loaded. how to do this?

这也提供了有趣的内容:

Is code injection possible in Java?


如果代码被用作库:

容易得多。攻击者可以像您所说的那样删除final修饰符,也可以使用ASM之类的东西生成一个新类,而该类首先没有使用final修饰符。如本仓库here所示,也可以只使用sun.misc.Unsafe。这样一来,他们便可以生成一个新的类,以扩展不再是最终类的子类。

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

执行此操作的方法可能更多,而且我本人还没有实际测试过这些方法,但是我认为这两种情况都可能取决于环境。

编辑:我忘了提到其中的某些内容在Java的更高版本中可能无法使用,在Java的更高版本中,对类操作和依赖项的访问受到更多限制。我将使用Java 8来解决所有这些问题,大多数人仍会这样做。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。