Are Interfaces Safe?

When using the Spring Framework the currently perceived wisdom is that writing your application to use Interfaces instead of implementations is the best practise.  It makes sense in terms of testing and decoupling class usage from particular implementations.  For nearly all the classes used in an application this makes absolute sense and, in fact, it’s recognised as one of the core strengths of the Spring Framework.

It occurs to me that, for classes with security sensitive functions, a possible security flaw exists.  It is conceivable that other nefarious implementations of the Interface could be injected into the application, which could capture data and interfere with the application’s processes.  In fact, were somebody not careful to indicate a sensitive class implementation as final, AOP could be used very handily to circumvent security and eavesdrop on many application activities.

For example, imagine an Interface for classes used to hash passwords similar to this one:

package ie.dsi.security.interfaces;
public interface Encryptor {
  public abstract String hash(String text, byte[] salt);
}

You might inject a SHA or an MD5 implementation when using it properly.  There is, however, nothing stopping someone from introducing their own evil implementation and using it to log passwords in clear text.

Correcting this issue is not as simple as it sounds.  Potentially some key-based nonsense could be implemented to ensure only valid Interface implementations are used, but this seems to invalidate all the gains made by using Interfaces in the first place.

It seems to me that the only safe recourse is to write your application to use the actual implementation in such cases.  Taking care, of course, to mark the implementation as final to prevent any sub-classing vulnerabilities.

 – Anthony Geoghegan

  1. #1 by Michal Bali on March 10, 2006 - 1:13 pm

    I have to disagree. You can modify the configuration files as easily as modify the bytecode. You can argue, that you can sign the bytecode (with the standard jarsigner), but I can say: sign the needed configuration files that don’t need to change during deployment as well.

    Maybe you should give a more concrete example.

    You have the same problem with third party libraries. I think the issue is with the security of the target environment rather than interfaces.

  2. #2 by Anthony Geoghegan on March 10, 2006 - 2:23 pm

    You can, of course, modify the configuration files, even easier than altering the byte code. That is not the point of the argument. The point is, if applications are programmed to use interfaces instead of implementations, it is trivial to substitute alternative implementations for classes with sensitive functionality when using the Spring Framework.

    The key is the use of the word trivial. The argument is all about not leaving easily exploited vulnerabilities in your code when you can easily avoid it.

    Signing the files could work, but I think it becomes unfeasible when you want to use third-party implementations.

    I wasn’t attacking the use of Interfaces in general, by the way, just trying to highlight a possibly insecure usage. I’m all for programming against interfaces whenever possible. It makes testing easier and dependency injection a snap.

  3. #3 by David Mulligan on March 10, 2006 - 3:21 pm

    Programming to concrete classes isn’t the answer either. It is possible to replace the implementation of concrete classes without going to the hassle of altering byte code or even a single configuration file. In fact you don’t even need to modify a single byte of the deployed project! Simply create a new concrete class using the class name and package structure of the one you wish to replace, package it up into a jar file and drop it into the lib directory of the JRE. This will make sure that the new implementation is higher up the classpath when you start the java process resulting in the new *unsafe* implementation being used. If an environment is not secure, then anything is possible.

  4. #4 by Anthony Geoghegan on March 10, 2006 - 3:39 pm

    It is indeed possible to replace concrete class implementations with your own evil code when you have the capability to monkey with the classpath for an application. Hence the use of “endorsed” folders for Endorsed Standards API implementations introduced in JDK 1.4.

    Once again, however, you’ve missed my point. It was not my intention to elucidate a completely secure mechanism for sensitive class functionality, merely to prevent the exploitation of a rather trivial exploit.

  5. #5 by Sidar Ok on April 13, 2007 - 5:52 pm

    I think we have to clear the border for the term “security”. Not trusting to the developer who has the appropriate rights for the application would be a paranoid approach rather than secure.

    With code access security (CAS) in .net, we can always let CLR to perform a stack walk and check the permissions of everyone in the caller – callee chain.

    But of course, there is no solution to prevent someone who is permitted to inject classes, but is an evil. And I don’t think there will be any until the time that we can programatically determine the “evil spirit” 🙂

  6. #6 by Anthony Geoghegan on April 16, 2007 - 7:28 am

    Actually it wasn’t legitimate developers I was worried about. A typical example of the dangers associated with this problem are when people write their own “Licence validators” for pirated software to subvert licence authentication. This is usually done by third party “black hats” and not members of the product’s development team.
    Interestingly, I don’t like security paraphernalia that can cause significant performance overhead either. I would consider repeated stack walks a serious performance worry. Perhaps the CAS system only walks the stack when a class is used for the first though.

  7. #7 by Sidar Ok on April 16, 2007 - 12:53 pm

    As far as I know CAS does not have a built-in mechanism for preventing execution of serious numbers of long stackwalks. The way reccomended by Microsoft to prevent this situation is 1 – Demand for the right once. 2 – If access granted, put a mark on top of the rights stack. 3 – Execute the operations 4 – Revert the assertion.

    The things might get a bit complex when we deal with exceptions and multithreading, because as it seems all these for steps should be ensured to be performed in one go.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: