javasecurityimmutabilitysecure-coding

Is limitation of accessibility for classes and their members a valid practice for more secure code?


According to Oracle Secure Coding Guideline Guideline 4-1/EXTEND-1 and Guideline 4-5/EXTEND-5 you should limit the accessibility of classes and their members as a security control against malicious override from an attacker.

Design classes and methods for inheritance or declare them final. Left non-final, a class or method can be maliciously overridden by an attacker. A class that does not permit subclassing is easier to implement and verify that it is secure.

How could an attacker actually exploit the below insecure class in real world scenario? Could he/she do it even if the class is already loaded in a running 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;
   }
}

If we are talking about a malicious insider who has access to the source code, couldn't he just remove the final modifier(if one was there already) or alter the class itself by any means in the first place?


Solution

  • That code isn't safe, whether there's a final keyword or not. It also depends wildly on the environment it's running in.

    If the JVM is already running:

    Much more difficult. I did notice some things with injection through C++, which could open up possibilities to things like runtime class generation/modification with ASM as the class is loading. This would require ASM to be included as a dependency, which most projects won't have. Using this method, it wouldn't matter if the class was final or not. From there, the attacker can just modify the isPasswordValid() method to always return true.

    If the class is already loaded, I don't think it's possible. See more here:

    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?

    This also provides an interesting read:

    Is code injection possible in Java?


    If the code is being used as a library:

    Much easier. The attacker could either remove the final modifier like you said, or generate a new class with something like ASM that doesn't have the final modifier in the first place. One could also just use sun.misc.Unsafe, as shown in this repo here. This would allow them to generate a new class that extends the no longer final class.

    Another method is to just use ASM to modify the class as it's loading, which would be easier.

    There are probably more ways of doing it, and I haven't actually tested any of these myself, but I think that it's possible in both situations depending on the environment.

    EDIT: I forgot to mention that some of this stuff might not work in later versions of Java, where class manipulation and dependency access is much more restricted. I'm basing all of this off of you using Java 8, which most people still do.

    EDIT 2: I just found this article here which provides a method for executing arbitrary code through debug mode, which can be used to manipulate the class also. Link