WebApp Sec mailing list archives

Re: [SC-L] By default, the Verifier is disabled on .Net and Java


From: Steve Brown <steve () kabarty com>
Date: Thu, 11 May 2006 11:08:52 +0100

App server ClassLoaders are a law unto themselves. If you try to use an
object whose class was loaded from a WAR file, in an EJB for example,
you will get a ClassCastException, even though the class is loaded and
available, because a different ClassLoader loaded it.

This is a whole area of expertise and black magic that takes even
respectable Java programmers a fair while to get their head around :) I
believe that Stephen de Vries is largely right, because the App Server
defines it's own ClassLoaders, it must be using the reflection APIs to
do this and that's why you see them behaving differently, however the
classes loaded from the javax.* packages (thus, HttpServletRequest,
ServletResponse etc)  will (probably) be loaded through the
standard/System ClassLoader when the App server starts up as opposed to
when the specific application is deployed. Thus they have 'static
knowledge' of the javax API classes, but do not have 'static knowledge'
of the classes you've deployed in your WAR/EAR as these are all loaded
by the vendor specific ClassLoader.

http://www.theserverside.com/articles/article.tss?l=ClassLoading gives a
good article about it, but suffice to say that App server class loading
is different to Desktop java classloading which generally uses only one
ClassLoader and has a much laxer policy on what it will allow, which is
different again to Applet ClassLoading...

I'm still not sure how you would exploit any of this for malicious
purposes anyway, in order to call a private method in someone elses code
you'd have to subvert the .class file containing that private method
anyway, in which case simply calling the private method would be the
least damage you could do. This, I believe, is why Applets require
signing before a browser will allow them to do things like opening
network sockets (except back to the host they were loaded from) and
writing to local file systems - so that the .class files can't be
subverted in this way.

Cheers,
Steve.

Stephen de Vries wrote:
Stephen de Vries wrote:
  
With application servers such as Tomcat, WebLogic etc, I think we have a
special case in that they don't run with the verifier enabled - yet they
appear to be safe from type confusion attacks.  (If you check the
startup scripts, there's no mention of running with -verify).
    

OK.

  
The difference between the app servers and a regular compiled Java app
is that the servers load  code dynamically and use reflection to access
fields and methods, so the app servers have no static knowledge of the
types defined in user code.
    

Apologies for the above incorrect statement.  App servers _do_ have
knowledge of the static type since they define the base classes in the
servlet and other API's.

  
The IllegalAccessError is generated when you try and access a private
method through the reflection API - and since the type checking is done
dynamically, it would be difficult (impossible?) to perform a type
confusion attack on code that isn't statically typed.  Code below
illustrates reflection access control in a simple app.
    

So, I'll rephrase this as: The Tomcat error looks suspiciously like a
reflection access control error, but it could be down to the type
checking done through the dynamic class loading - and not necessarily
the reflection API.

  
package classloader;

import java.lang.reflect.Method;
import somepackage.MyData;

public class Main {

    public Main() {
    }

    public static void main(String[] args) {
        try {

            Class myClass = MyData.class;
            Object obj = myClass.newInstance();
            Method m = myClass.getDeclaredMethod("getName", new Class[] {});
            System.out.println(m.invoke(obj, new Object[] {}).toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

package somepackage;

public class MyData {
    private String name;

    public MyData() {
        name = "No one can read me";
    }

    private String getName() {
        return name;
    }
}

Executing the app produces:

java.lang.IllegalAccessException: Class classloader.Main can not access
a member of class somepackage.MyData with modifiers "private"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
        at java.lang.reflect.Method.invoke(Method.java:578)
        at classloader.Main.main(Main.java:41)



    


  

-------------------------------------------------------------------------
Sponsored by: Watchfire

Methodologies & Tools for Web Application Security Assessment
With the rapid rise in the number and types of security threats, web 
application security assessments should be considered a crucial phase in 
the development of any web application. What methodology should be 
followed? What tools can accelerate the assessment process? 
Download this whitepaper today!

https://www.watchfire.com/securearea/whitepapers.aspx?id=701300000007t9h
--------------------------------------------------------------------------


Current thread: