Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Problems/Weaknesses with JAAS

843811Nov 29 2001 — edited Apr 25 2002
Basically the problem is this: the plug-in LoginModule model of JAAS seems to allow clients to falsely authenticate (or at the very least is VERY prone to this).

In particular, the manner in which a Subject is associated with a valid/authenticated Principal is dangerous and error-prone/open to security holes. This danger is increased by JAAS' assumption that a Subject with a Principal in it (once it is past the LoginContext) is authenticated.

What makes the above problems most worrisome, perhaps are that almost everyone I have seen implementing JAAS, has made a misinterpretation of how to use JAAS, that makes this potential weakness wide-open. Which brings me to how I came upon this problem in the first place.

Have you ever used WebLogic or seen its tutorials/examples? You can find their JAAS example (to which I refer below) in the pdf: http://e-docs.bea.com/wls/docs61/pdf/security.pdf (I believe you want pages 64-74). WebLogic I believe, goes about this all wrong. They have misunderstood the reason behind the pluggabiliy and flexibility of JAAS. Simply put, they allow the client to use their own LoginModules, as well as CallBackHandlers.

This is not only dangerous, but also wrong and a misuse of JAAS (but really it's a big security-hole/risk that JAAS needs to close up - either by training/documentation or an API change). The WebLogic implementation allows the client to get a reference (in the module) to the LoginContext's Subject and authenticate themselves (i.e. associate a Principal with the subject). Simply associating a Principal with a Subject is, in JAAS, authentication.

In JAAS, the AccessController checks permissions by looking at the Principal in the Subject and seeing if that Principal is granted the permission by checking with the Policy class (this is called Authorization). What it does NOT do, is see if that Subject has the RIGHT to hold that Principal. Rather, it assumes the Subject is authenticated.

In other words, a user who is allowed to use their own Module (as WebLogic's example shows) could do something like this:
    //THEIR LOGIN MODULE (SOME CODE CUT-OUT FOR BREVITY)
    public class BasicModule implements LoginModule
    {
         private NameCallback strName;
         private PasswordCallback strPass;
         private CallbackHandler myCB;
         private Subject subj;

         //INITIALIZE THIS MODULE
           public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
           {
                  try
                  {
                       //SET SUBJECT
                         subj = subject;  	//NOTE: THIS GIVES YOU REFERENCE TO LOGIN CONTEXT'S SUBJECT
                                                 	// AND ALLOWS YOU TO PASS IT BACK TO THE LOGIN CONTEXT
				// THIS IS HOW JAAS LoginContext WORKS

                       //SET CALLBACKHANDLERS
                         strName = new NameCallback("Your Name: ");
                         strPass = new PasswordCallback("Password:", false);
                         Callback[] cb = { strName, strPass };

                       //HANDLE THE CALLBACKS
                         callbackHandler.handle(cb);

                  } catch (Exception e) { System.out.println(e); }
    }

     //LOG THE USER IN
       public boolean login() throws LoginException
       {
          //TEST TO SEE IF SUBJECT HOLDS ANYTHING YET
          System.out.println( "PRIOR TO AUTHENTICATION, SUBJECT HOLDS: " + subj.getPrincipals().size() + " Principals");

          //SUBJECT AUTHENTICATED - BECAUSE SUBJECT NOW HOLDS THE PRINCIPAL
           MyPrincipal m = new MyPrincipal("Admin");
           subj.getPrincipals().add(m);
           return true;	// DIDN'T DO ANYTHING TO CHECK, BUT AS A CLIENT I RETURN IT
         }

         public boolean commit() throws LoginException
         {
               return true;
         }
    }
(Sorry for all that code)
I tested the above code, and it fully associates the Subject with its principal and with the Subject contained in LoginContext. So my question is, where in the process (and code) can we put the LoginContext and Modules so that a client cannot do this? With the above example, there is no Security. (a call to: myLoginContext.getSubject().doAs(...) will work)

I think the key here is to understand JAAS's plug-in security model to mean:
(Below are my words)

The point of JAAS is to allow an application to use different ways of
authenticating without changing the application's code, but NOT to
allow the user to authenticate however they want.

In WebLogic's example, they unfortunately seem to have used the latter understanding, i.e. "allow the user to authenticate however they want." That is not security. So how do we solve this? We need to put JAAS on the server side (with no direct JAAS client-side), and that includes the LoginModules as well as LoginContext.

A further problem that needs to be solved is that JAAS:
1. Assumes authentication with a populated Subject
2. Allows for no way to automatically in a JVM check authorization/authentication.

This means that applications that use JAAS are not truly pluggable. Think about this:

What if I have an application that uses JAAS security. In addition, this app. allows for plug-in of JavaBeans. Every month or so, we purchase a third-party bean and put it into our application. The problem? We cannot have JAAS (or role-based) security on the JavaBeans we buy. We would have to either reverse-engineer and change the code, or change the byte code. This is because there is no way to say to the JVM or security manager:
"Call a Permission check when you hit method com.MyCom.doSmth()"

Instead, if I want a Permission check for that method, I need to explicity call AccessController INSIDE the method (or before EVERY call to it everywhere in my application and the plug-in JavaBeans).
e.g. AccessController.checkPermission(...)

There are only two ways I can currently see around this:
1. Alter the JVM (this is largely up to sun, and will be a big problem as it might decrease performance.)
NOTE: That is a "might" not a garauntee - who knows till we try
2. Alter ClassLoaders to change the bytecode of the class bytes it loads to have calls to AccessController.
A. This could be done by having a ".xml" file which lists the methods (and of which classes they are), and the ClassLoader will check each class it loads and alter the byte-code accordingly for those methods. This is hard, but would not require a JVM change. It could even be solved by -Xbootclasspath for the ClassLoaders. However, altering byte-code is not the best idea, and might be wrought with problems. As well, it might add too much to JVM / App startup time.

Regardless of whether you think either of the above solutions is feasible or even intelligent suggestions, the fact still remains that JAAS and the Java role-based security is inadequate for the Java App world of collaboration and third-party software (which is the whole point and push behind JavaBeans).

Everyone, please comment on all of this and let me know what you think. Tear my arguments apart. Offer solutions. Throw out more problems I missed.

Thanks,
Robert

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 23 2002
Added on Nov 29 2001
5 comments
235 views