Secure Coding mailing list archives
By default, the Verifier is disabled on .Net and Java
From: dinis at ddplus.net (Dinis Cruz)
Date: Thu, 04 May 2006 03:40:07 +0100
Ok, I just did some further tests and I think I can say that Java (version 1.5.0_06) has similar verification issues to the ones I discovered on the .Net Framework (see links in my previous post). Here is a full description of my test (which is a variation of the one done by Stephen de Vries in the original discussion about type safety). ------------- Objective: Call a private method directly that belongs to a different class (something that should not be possible to do) Test environment: Mac OS X10.4.6 java -version java version "1.5.0_06" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112) Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing) Step by Step description of test: Start by creation the File: publicPrivate.java ****************** class publicPrivate { public static void main(String[] args) { System.out.println("Hello World!"); //Display the string. externalClass.publicMethod(); externalClass.publicMethod(); } } class externalClass { public static void publicMethod() { System.out.println("Inside the Public Method"); } private static void privateMethod() { System.out.println("Inside the Private Method"); } } ****************** Compile this using javac publicPrivate.java and you get two class files: publicPrivate.class and externalClass.class execute java publicPrivate and you will get Hello World! Inside the Public Method Inside the Public Method Note that if I change on the publicPrivate.java file the lines externalClass.publicMethod(); externalClass.publicMethod(); to externalClass.publicMethod(); externalClass.privateMethod(); I will get the following compilation error: publicPrivate.java:7: privateMethod() has private access in externalClass externalClass.privateMethod(); ^ 1 error This makes sense since this is the compiler detecting that we are trying to access a private member directly (note: this is also what happens in .Net's C# compiler). It also means that (like in my .Net examples) I will have to manipulate directly the bytecode of the class that I want to change Using jEdit Oolong plug-in I disassembled the publicPrivate.class file, creating the file: publicPrivate.j (this is a slightly edited version of the Oolong disassemble result since the original version didn't compile) ****************** .class public publicPrivate .super java/lang/Object .method public <init>()V .limit stack 1 .limit locals 1 aload_0 invokespecial java/lang/Object/<init>()V return .end method .method public static main([Ljava/lang/String;)V .limit stack 2 getstatic java/lang/System/out Ljava/io/PrintStream; ldc "Hello World! - After Oolong disassemble" invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V invokestatic externalClass/publicMethod()V invokestatic externalClass/publicMethod()V return .end method ************** note the change: from: ldc "Hello World!" to: ldc "Hello World! - After Oolong disassemble" I also had some problems with getting the jEdit Oolong plug-in to assemble the publicPrivate.j file, so I used jasmin instead: java -jar jasmin-2.2/jasmin.jar PublicPrivate.j Generated: publicPrivate.class Executing java publicPrivate shows: Hello World!- After Oolong disassemble Inside the Public Method Inside the Public Method Now, in jEdit, on the publicPrivate.j file, I make the following change from: invokestatic externalClass/publicMethod()V invokestatic externalClass/publicMethod()V to: invokestatic externalClass/publicMethod()V invokestatic externalClass/privateMethod()V Then save it and run jasmin again java -jar jasmin-2.2/jasmin.jar PublicPrivate.j Generated: publicPrivate.class execute java publicPrivate and: Hello World!- After Oolong disassemble Inside the Public Method Inside the Private Method Bingo! We successfully invoked the private method. Now, just to confirm that this is against verification (and that the verifier is disabled by default) java -noverify publicPrivate (produces the same result) Hello World!- After Oolong disassemble Inside the Public Method Inside the Private Method java -verify publicPrivate (throws an verification error) Hello World!- After Oolong disassemble Inside the Public Method Exception in thread "main" java.lang.IllegalAccessError: tried to access method externalClass.privateMethod()V from class publicPrivate at publicPrivate.main(PublicPrivate.j) This should prove that the verifier is not enabled by default on java files loaded from the local computer. What is interesting about this example is that we are not even doing a Type Confusion attack and trying to break type safety. Ironically this same example doesn't work in the .Net CLR since the JIT detects this it (which is why in my 'Rooting the CLR' presentation I patch the JIT directly :) Question for the Java gurus on this list (remember that I am not very good with Java so I might have got some of this wrong), can you re-confirm this test, and also see what happens on other java execution environments (for example on Apache) Thanks Best regards Dinis Cruz Owasp .Net Project www.owasp.net
Current thread:
- By default, the Verifier is disabled on .Net and Java, (continued)
- By default, the Verifier is disabled on .Net and Java Stephen de Vries (May 10)
- By default, the Verifier is disabled on .Net and Java Dinis Cruz (May 12)
- By default, the Verifier is disabled on .Net and Java Stephen de Vries (May 13)
- By default, the Verifier is disabled on .Net and Java Wall, Kevin (May 02)
- By default, the Verifier is disabled on .Net and Java David Eisner (May 03)
- By default, the Verifier is disabled on .Net and Java Dinis Cruz (May 03)
- By default, the Verifier is disabled on .Net and Java Tim Hollebeek (May 04)
- By default, the Verifier is disabled on .Net and Java Dinis Cruz (May 12)
- By default, the Verifier is disabled on .Net and Java David Eisner (May 03)
- By default, the Verifier is disabled on .Net and Java Michael Silk (May 03)
- By default, the Verifier is disabled on .Net and Java Dinis Cruz (May 03)
- By default, the Verifier is disabled on .Net and Java David Eisner (May 04)
- By default, the Verifier is disabled on .Net and Java Stephen de Vries (May 04)
- By default, the Verifier is disabled on .Net and Java Michael Silk (May 04)