[SC-L] By default, the Verifier is disabled on .Net and Java
Here is a more detailed explanation of why (in my previous post) I said: "99% of .Net and Java code that is currently deployed is executed on an environment where the VM verifier is disabled, ." -- In .Net the verifier (the CLR function that checks for type safety) is only enabled on partial trust .Net environments. For example, in Full Trust .Net you can successfully assign Type A to Type B (also called a Type Confusion attack) which clearly breaks type safety. I have done some research on this topic, and on my spare time I was able to find several examples of these situations: Possible Type Confusion issue in .Net 1.1 (only works in FullTrust) (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx) Another Full Trust CLR Verification issue: Exploiting Passing Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/393.aspx) Another Full Trust CLR Verification issue: Changing Private Field using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/394.aspx) Another Full Trust CLR Verification issue: changing the Method Parameters order (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) C# readonly modifier is not enforced by the CLR (when in Full Trust (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) Also related: JIT prevents short overflow (and PeVerify doesn't catch it) (http://owasp.net/blogs/dinis_cruz/archive/2006/01/10/422.aspx) and ANSI/UNICODE bug in System.Net.HttpListenerRequest (http://www.owasp.net//blogs/dinis_cruz/archive/2005/12/17/349.aspx) Here is Microsoft's 'on the record' comment about this lack of verification (and enforcement of type safety) on Full Trust code (note: I received these comments via the MSRC): "... Some people have argued that Microsoft should always enforce type safety at runtime (i.e. run the verifier) even if code is "Fully Trusted". We've chosen not to do this for a number of reasons (e.g. historical, perf, etc). There are at least two important things to consider about this scenario: 1) Even if we tried to enforce type safety using the verifier for Fully Trusted code, it wouldn't prevent Fully Trusted from accomplishing the same thing in 100 other different ways. In other words, your example accessed an object as if it were a different incompatible type - The verifier could have caught this particular technique that allowed him to violate type safety. However, he could have accomplished the same result using private reflection, direct memory access with unsafe code, or indirectly doing stuff like using PInvoke/native code to disable verification by modifying the CLR's verification code either on disk or in memory. There would be a marginal benefit to insuring people wrote "cleaner" more "type safe" code by enforcing verification at runtime for Full Trust, but you wouldn't get any additional security benefits because you can perform unverifiable actions in dozens of ways the verifier won't prevent if you are Fully Trusted. 2) As mentioned at the end of #1 above, one argument is that it's good for programmers (even fully trusted ones) to follow type safety rules, and doing runtime verification would keep people writing cleaner code. However, we don't need to do the verification at "runtime" in order to encourage good type safety hygiene. Instead, we can rely on our languages to do this for us. For example, C# and VB by default ensure that you produce verifiable code. If you've written your code in a language like C#, you're not going to run into cases where you've accidentally created unverifiable code (This can be seen in the example posted on the blog since you needed to use the low level assembler to hack up a program initially compiled in C#). Given that you can't prevent Fully Trusted code from doing unverifiable things at runtime, there's only a marginal difference between encouraging type safety at compile time vs at runtime for the Fully Trusted code developer. I hope that helps to convey the message on where Microsoft stands with this issue. ..." Unfortunately Java is not much better. By default most Java code is also executed with -noverify. Here is a good explanation from this (http://lists.grok.org.uk/pipermail/full-disclosure/2006-March/044505.html) thread (which I started) : "... >> I am not a Java expert, but I think that the Java Verifier is NOT >> used on Apps that >> are executed with the Security Manager disabled (which I believe is the default >> setting) or are loaded from a local disk (see "... applets loaded via the file system >> are not passed through the byte code verifier" in http://java.sun.com/sfaq/) > I believe that as of Java 1.2, all Java code except the core > libraries must > go through the verifier, unless it is specifically disabled (java > -noverify). I had the same intuition about the verifier, but have just tested this and it is not the case. It seems that
[SC-L] By default, the Verifier is disabled on .Net and Java
in reply to >Dinis Cruz dinis at ddplus.net >Sun May 14 03:40:20 EDT 2006 <...skipped...> >So in an environment where you have a solid Security Policy (enforced by >a Security Manager) but the verifier is NOT enabled, then to jump out of >the sandbox all that you need to do is to create a Type Confusion >exploit that allows you to access a private member that either: calls >the protected resource directly or disables the Security Manager (which >based on the description provided is the demo that I think Ed Felten did).I guess this is exactly the logic that was behind the implementation decision that by default Code isn't verified when and only when it is granted "All Permissions" mentioned here http://archives.java.sun.com/cgi-bin/wa?A2=ind0107&L=java-security&P=1305 Though the post at the link avove talks only about boot strap classes, i guess this policy is now implemented across the whole JVM (obviously some digging through the java sources would be needed to confirm this) __ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
[Moderator: Feel free to discard some or all of Dinis' original post below. I wasn't sure how much to trim because I don't know how much people have been paying attention to this particular discussion and I didn't want them to loose context and have to resort to searching the archives.] It might be nice if the Java VM would / could distinguish betw running from a LOCAL disk vs a remote networked disk (NFS, Samba share, etc.) and enable tye byte code verify automagically for any classes loaded remotely. That doesn't seem too different (in terms of attack vectors) of running applets locally using remotely loaded classes. A similar thing might also be done if any jars, zip files, .class files, or the directories in which they reside were writable by anyone other than root (or equivalent on Windows, MacOS, etc.) or the user id executing the Java program. Of course that's not too likely to be too portable across the various supported OSes, so perhaps that's why Sun choose not to do it. Perhaps asking / begging Microsoft to do a similar thing for .NET assemblies might be an easier sell because they wouldn't face the OS portability issue (as much). Dinis: I deliberately did not cross-post to the owasp-dotnet list. You can if you wish. -kevin --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED]Phone: 614.215.4788 "The reason you have people breaking into your software all over the place is because your software sucks..." -- Former whitehouse cybersecurity advisor, Richard Clarke, at eWeek Security Summit -Original Message- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Dinis Cruz > Sent: Tuesday, May 02, 2006 7:48 PM > To: 'Secure Coding Mailing List' > Cc: '[EMAIL PROTECTED]' > Subject: [SC-L] By default, the Verifier is disabled on .Net and Java > > > Here is a more detailed explanation of why (in my previous post) I said: "99% of .Net and Java code that is currently deployed is executed on an environment where the VM verifier is disabled, ." > > -- > > In .Net the verifier (the CLR function that checks for type safety) is only enabled on partial trust .Net environments. > > For example, in Full Trust .Net you can successfully assign Type A to Type B (also called a Type Confusion attack) which clearly breaks type safety. > > I have done some research on this topic, and on my spare time I was able to find several examples of these situations: > > > Possible Type Confusion issue in .Net 1.1 (only works in FullTrust) (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx) > Another Full Trust CLR Verification issue: Exploiting Passing Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/393.aspx) > Another Full Trust CLR Verification issue: Changing Private Field using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/394.aspx) > Another Full Trust CLR Verification issue: changing the Method Parameters order (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) > C# readonly modifier is not enforced by the CLR (when in Full Trust (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) > > Also related: > > JIT prevents short overflow (and PeVerify doesn't catch it) (http://owasp.net/blogs/dinis_cruz/archive/2006/01/10/422.aspx) > > and ANSI/UNICODE bug in System.Net.HttpListenerRequest (http://www.owasp.net//blogs/dinis_cruz/archive/2005/12/17/349.aspx) > > Here is Microsoft's 'on the record' comment about this lack of verification (and enforcement of type safety) on Full Trust code (note: I received these comments via the MSRC): > > "... > Some people have argued that Microsoft should always enforce type safety > at runtime (i.e. run the verifier) even if code is "Fully Trusted". > We've chosen not to do this for a number of reasons (e.g. historical, > perf, etc). There are at least two important things to consider about > this scenario: > > 1) Even if we tried to enforce type safety using the verifier for Fully > Trusted code, it wouldn't prevent Fully Trusted from accomplishing the > same thing in 100 other different ways. In other words, your example > accessed an object as if it were a different incompatible type - The > verifier could have caught this particular technique that allowed him to > violate type safety. However, he could have accomplished the same > result using private reflection, direct memory access with unsafe code, > or indirectly doing stuff like using PInvoke/native code to disable > verification by modifying the CLR's verification code either on disk or > in memory. There woul
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
Two important clarifications for Java (based on my experiments): 1) The verifier IS enabled for the classes that come with the Java platform, such as those in rt.jar. So, for example, if you create a class that tries to set System.security (the private variable that points to the SecurityManager instance), you get a verification exception. (If this was possible, it would allow a complete bypass of the Java sandbox). 2) The verifier also seems to be enabled for classes running inside Tomcat. I’m not sure about other J2EE containers. So I don’t think it’s fair to say that most Java code is running without verification. But Denis is right. There is a real problem with verification, as demonstrated in the message below. This is a clear violation of the Java VM Spec, yet my messages to the team at Sun developing the new verifier have been ignored. And it’s a real issue, given the number of applications that rely on libraries they didn’t compile. I don’t think a real explanation of how the Sun verifier actually works is too much to ask, given the risk. --Jeff From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Dinis Cruz Sent: Tuesday, May 02, 2006 7:48 PM To: 'Secure Coding Mailing List' Cc: '[EMAIL PROTECTED]' Subject: [SC-L] By default, the Verifier is disabled on .Net and Java Here is a more detailed explanation of why (in my previous post) I said: "99% of .Net and Java code that is currently deployed is executed on an environment where the VM verifier is disabled, ." -- In .Net the verifier (the CLR function that checks for type safety) is only enabled on partial trust .Net environments. For example, in Full Trust .Net you can successfully assign Type A to Type B (also called a Type Confusion attack) which clearly breaks type safety. I have done some research on this topic, and on my spare time I was able to find several examples of these situations: Possible Type Confusion issue in .Net 1.1 (only works in FullTrust) (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx) Another Full Trust CLR Verification issue: Exploiting Passing Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/393.aspx) Another Full Trust CLR Verification issue: Changing Private Field using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/394.aspx) Another Full Trust CLR Verification issue: changing the Method Parameters order (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) C# readonly modifier is not enforced by the CLR (when in Full Trust (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) Also related: JIT prevents short overflow (and PeVerify doesn't catch it) (http://owasp.net/blogs/dinis_cruz/archive/2006/01/10/422.aspx) and ANSI/UNICODE bug in System.Net.HttpListenerRequest (http://www.owasp.net//blogs/dinis_cruz/archive/2005/12/17/349.aspx) Here is Microsoft's 'on the record' comment about this lack of verification (and enforcement of type safety) on Full Trust code (note: I received these comments via the MSRC): "... Some people have argued that Microsoft should always enforce type safety at runtime (i.e. run the verifier) even if code is "Fully Trusted". We've chosen not to do this for a number of reasons (e.g. historical, perf, etc). There are at least two important things to consider about this scenario: 1) Even if we tried to enforce type safety using the verifier for Fully Trusted code, it wouldn't prevent Fully Trusted from accomplishing the same thing in 100 other different ways. In other words, your example accessed an object as if it were a different incompatible type - The verifier could have caught this particular technique that allowed him to violate type safety. However, he could have accomplished the same result using private reflection, direct memory access with unsafe code, or indirectly doing stuff like using PInvoke/native code to disable verification by modifying the CLR's verification code either on disk or in memory. There would be a marginal benefit to insuring people wrote "cleaner" more "type safe" code by enforcing verification at runtime for Full Trust, but you wouldn't get any additional security benefits because you can perform unverifiable actions in dozens of ways the verifier won't prevent if you are Fully Trusted. 2) As mentioned at the end of #1 above, one argument is that it's good for programmers (even fully trusted ones) to follow type safety rules, and doing runtime verification would keep people writing cleaner code. However, we don't need to do the verification at "runtime" in order to encourage good type safety hygiene. Instead, we can rely on our languages to do this for us. For example, C# and VB by default en
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 3 May 2006, at 06:48, Dinis Cruz wrote: Here is a more detailed explanation of why (in my previous post) I said: "99% of .Net and Java code that is currently deployed is executed on an environment where the VM verifier is disabled, ." -- In .Net the verifier (the CLR function that checks for type safety) is only enabled on partial trust .Net environments. Java has implemented this a bit differently, in that the byte code verifier and the security manager are independent. So you could for example, run an application with an airtight security policy (equiv to partial trust), but it could still be vulnerable to type confusion attacks if the verifier was not explicitly enabled. To have both enabled you'd need to run with: java -verify -Djava.security.policy ... regards, -- Stephen de Vries Corsaire Ltd E-mail: [EMAIL PROTECTED] Tel:+44 1483 226014 Fax:+44 1483 226068 Web:http://www.corsaire.com ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Wall, Kevin wrote: >> same intuition about the verifier, but have just tested >> this and it is not the case. It seems that the -noverify is the >> default setting! If you want to verify classes loaded from the local >> filesystem, then you need to explicitly add -verify to the cmd line. >> Is this (still) true? The -verify and -noverify flag are no longer documented [1], although they are still accepted. I did a little experiment (with my default 1.5 VM). I compiled a HelloWorld program, then changed a few byes in the class file with a hex editor. -8<-- $ java -cp . HelloWorld Exception in thread "main" java.lang.ClassFormatError: Interface name has bad constant pool index 13056 in class file HelloWorld at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) $ java -cp . -verify HelloWorld Exception in thread "main" java.lang.ClassFormatError: Interface name has bad constant pool index 13056 in class file HelloWorld at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) $ java -cp . -noverify HelloWorld # # An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_ACCESS_VIOLATION (0xc005) at pc=0x6d7415fb, pid=3512, tid=2260 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode) # Problematic frame: # V [jvm.dll+0x615fb] # # An error report file with more information is saved as hs_err_pid3512.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # -8<-- -David [1] http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
David Eisner wrote... > Wall, Kevin wrote: The correct attribution for bring this up (and the one whom you are quoting) is Dinis Cruz. > >> same intuition about the verifier, but have just tested > >> this and it is not the case. It seems that the -noverify is the > >> default setting! If you want to verify classes loaded from the local > >> filesystem, then you need to explicitly add -verify to the cmd line. > > Is this (still) true? The -verify and -noverify flag are no longer > documented [1], although they are still accepted. > > I did a little experiment (with my default 1.5 VM). I compiled a > HelloWorld program, then changed a few byes in the class file with a > hex editor. Perhaps no longer true (at least one could hope), but I can't take credit for the part you quoted above. That was Dinis. Also, from the results of your test, it seems to indicate that SOME TYPE of verification is taking place, but if all you did was change a few ARBITRARY bytes in the .class file, I don't think that proves the byte code verifier is being being run in it's entirety. IIRC, the discussion was around the issue of 'type safety'. It's hard to see how a HelloWorld program would show that. It's entirely possibly that the (new 1.5) default just does some surface level of byte code verification (e.g., verify that everything is legal "op codes" / byte code) before HotSpot starts crunching on it and that this works differently if either the '-verify' or '-noverify' flags are used. E.g., suppose that '-verify' flag, does some deeper-level analysis, such as checks to ensure type safety, etc, whereas the '-noverify' doesn't even validate the byte codes are legal op codes or that the .class file has a legal format. This might even make sense because checking for valid file format and valid Java "op codes" ought to be fairly "cheap" checks compared to the deeper analysis required for things like type safety. You didn't discuss details of what bits you tweaked, so I'm not quite yet ready to jump up and down for joy and conclude that Sun has now seen the light and has made the 1.5 JVM default to run the byte code through the *complete* byte code verifier. I think more tests are either necessary or someone at Sun who can speak in some official capacity steps up and gives a definitive word one way or another on this. -kevin --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED] Phone: 614.215.4788 "Linux *is* user-friendly. It's just choosy about its friends." - Robert Slade, http://sun.soci.niu.edu/~rslade/bkl3h4h4.rvw This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
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 ()V .limit stack 1 .limit locals 1 aload_0 invokespecial java/lang/Object/()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 t
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Verifier in 1.5 is definately OFF by default: to confirm this do the following: 1. Create this class: == public class Foo { public static int k = 23; static { System.out.println("initially k: " + k); } public static void m(){ System.out.println("m() k: " + k); } } == 2. Compile it. 3. Create this class == public class Test { public static void main(String[] args){ Foo.k = 34; Foo.m(); } } == 4. Compile it. 5. Run it like so: 5a. java Test 5b. java -verify Test 6. Change "Foo.java" like so: == public class Foo { private static int k = 23; static { System.out.println("initially k: " + k); } public static void m(){ System.out.println("m() k: " + k); } } == (note "k" is now private). 7. recompile "Foo.java" (DO NOT recompile Test.java") 8. run Test.java like so: 8a. java Test 8b. java -verify Test Note the differences ... Tested with === java version "1.5.0_06" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05) Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode) === -- Michael On 5/4/06, Wall, Kevin <[EMAIL PROTECTED]> wrote: David Eisner wrote... > Wall, Kevin wrote: The correct attribution for bring this up (and the one whom you are quoting) is Dinis Cruz. > >> same intuition about the verifier, but have just tested > >> this and it is not the case. It seems that the -noverify is the > >> default setting! If you want to verify classes loaded from the local > >> filesystem, then you need to explicitly add -verify to the cmd line. > > Is this (still) true? The -verify and -noverify flag are no longer > documented [1], although they are still accepted. > > I did a little experiment (with my default 1.5 VM). I compiled a > HelloWorld program, then changed a few byes in the class file with a > hex editor. Perhaps no longer true (at least one could hope), but I can't take credit for the part you quoted above. That was Dinis. Also, from the results of your test, it seems to indicate that SOME TYPE of verification is taking place, but if all you did was change a few ARBITRARY bytes in the .class file, I don't think that proves the byte code verifier is being being run in it's entirety. IIRC, the discussion was around the issue of 'type safety'. It's hard to see how a HelloWorld program would show that. It's entirely possibly that the (new 1.5) default just does some surface level of byte code verification (e.g., verify that everything is legal "op codes" / byte code) before HotSpot starts crunching on it and that this works differently if either the '-verify' or '-noverify' flags are used. E.g., suppose that '-verify' flag, does some deeper-level analysis, such as checks to ensure type safety, etc, whereas the '-noverify' doesn't even validate the byte codes are legal op codes or that the .class file has a legal format. This might even make sense because checking for valid file format and valid Java "op codes" ought to be fairly "cheap" checks compared to the deeper analysis required for things like type safety. You didn't discuss details of what bits you tweaked, so I'm not quite yet ready to jump up and down for joy and conclude that Sun has now seen the light and has made the 1.5 JVM default to run the byte code through the *complete* byte code verifier. I think more tests are either necessary or someone at Sun who can speak in some official capacity steps up and gives a definitive word one way or another on this. -kevin --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED]Phone: 614.215.4788 "Linux *is* user-friendly. It's just choosy about its friends." - Robert Slade, http://sun.soci.niu.edu/~rslade/bkl3h4h4.rvw This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
David Eisner wrote: Wall, Kevin wrote: same intuition about the verifier, but have just tested this and it is not the case. It seems that the -noverify is the default setting! If you want to verify classes loaded from the local filesystem, then you need to explicitly add -verify to the cmd line. Is this (still) true? The -verify and -noverify flag are no longer documented [1], although they are still accepted. Yes it is still true (see my last email on this thread) I did a little experiment (with my default 1.5 VM). I compiled a HelloWorld program, then changed a few byes in the class file with a hex editor. By doing this this (unless you were very lucky in your changes) you will either create an invalid Java bytecode instruction, or will corrupt the .class file So the errors you are getting below don't look like verifier errors (although I can't really explain why the --noverify throws a different error). Can you try to disassemble this corrupted class so see if we can get more details about where the bytecode error is Thanks Dinis Cruz Owasp .Net Project www.owasp.net -8<-- $ java -cp . HelloWorld Exception in thread "main" java.lang.ClassFormatError: Interface name has bad constant pool index 13056 in class file HelloWorld at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) $ java -cp . -verify HelloWorld Exception in thread "main" java.lang.ClassFormatError: Interface name has bad constant pool index 13056 in class file HelloWorld at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) $ java -cp . -noverify HelloWorld # # An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_ACCESS_VIOLATION (0xc005) at pc=0x6d7415fb, pid=3512, tid=2260 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode) # Problematic frame: # V [jvm.dll+0x615fb] # # An error report file with more information is saved as hs_err_pid3512.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # -8<-- -David [1] http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Wall, Kevin wrote: Also, from the results of your test, it seems to indicate that SOME TYPE of verification is taking place, but if all you did was change a few ARBITRARY bytes in the .class file, I don't think that proves the byte code verifier is being being run in it's entirety. I agree with this analysis and think that the error on David's test was caused by a malformed bytecode instruction It's entirely possibly that the (new 1.5) default just does some surface level of byte code verification (e.g., verify that everything is legal "op codes" / byte code) Well, some level of verification (or bytecode check) must always occur during the conversion from bytecode to native code (but this has nothing to do with type safety) before HotSpot starts crunching on it and that this works differently if either the '-verify' or '-noverify' flags are used. E.g., suppose that '-verify' flag, does some deeper-level analysis, such as checks to ensure type safety, etc, whereas the '-noverify' doesn't even validate the byte codes are legal op codes or that the .class file has a legal format. This might even make sense because checking for valid file format and valid Java "op codes" ought to be fairly "cheap" checks compared to the deeper analysis required for things like type safety. I am a little bit confused here, isn't Java an open platform and almost Open Source? If so, shouldn't issues like this be quite well documented? (if not on official documentation, at least on online discussion threads) I have a couple books on java that discuss the verification process, but they are quite old, so It would be good to know the details about the current verification process (as implemented in the latest version) You didn't discuss details of what bits you tweaked, so I'm not quite yet ready to jump up and down for joy and conclude that Sun has now seen the light and has made the 1.5 JVM default to run the byte code through the *complete* byte code verifier. Unfortunately I don't think that Sun has seen the light on this one (and neither has Microsoft) I think more tests are either necessary or someone at Sun who can speak in some official capacity steps up and gives a definitive word one way or another on this. Talking about Sun, where are they? I know that Jeff Williams (Owasp) have tried several times to get a response from them on these issues but has been unsuccessful. Aren't they (Sun) supposed to be much more open and transparent about Java? (at least when compared to Microsoft) I am sure that there must be people from Sun on this list (likewise from Microsoft), and it would be great if they joined this discussion so that we can understand exactly what is going on. Best regards Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 5/4/06, Dinis Cruz <[EMAIL PROTECTED]> wrote: Wall, Kevin wrote: > Also, from the results of your test, it seems to indicate that SOME TYPE > of verification is taking place, but if all you did was change a few > ARBITRARY bytes in the .class file, I don't think that proves the > byte code verifier is being being run in it's entirety. I agree with this analysis and think that the error on David's test was caused by a malformed bytecode instruction > It's entirely possibly that the (new 1.5) default just does some > surface level of byte code verification (e.g., verify that everything > is legal "op codes" / byte code) Well, some level of verification (or bytecode check) must always occur during the conversion from bytecode to native code (but this has nothing to do with type safety) > before HotSpot starts crunching > on it and that this works differently if either the '-verify' or > '-noverify' flags are used. E.g., suppose that '-verify' flag, does > some deeper-level analysis, such as checks to ensure type safety, etc, > whereas the '-noverify' doesn't even validate the byte codes are > legal op codes or that the .class file has a legal format. This might > even make sense because checking for valid file format and valid > Java "op codes" ought to be fairly "cheap" checks compared to the > deeper analysis required for things like type safety. > I am a little bit confused here, isn't Java an open platform and almost Open Source? The source for the j2se sdk is available (i.e. all the classes) and the source for the runtime is available as well, but under a different, special license. If so, shouldn't issues like this be quite well documented? Actually, the verification process is documented here: http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#88597 -- Michael ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Dinis Cruz wrote: > 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). [...] > This should prove that the verifier is not enabled by default on java > files loaded from the local computer. First, apologies to Dinis and Kevin for the mis-attribution. I agree, based on the various experiments, it looks like the bytecode verifier is still not enabled by default for locally loaded class files. I'm not sure why my randomly modified HelloWorld.class file behaved differently in the -verify / -noverify cases. If I have more time, I'll dig into it. As mentioned, the source code for the jdk is available under the Sun Community Source License. [1] Unfortunately, this license doesn't permit redistribution of code to non-licensees, so I'll just describe what I found when I took a (non-exhaustive) look. j2se/src/share/bin/java.c: java {-verify, -verifyremote, -noverify} are aliases for options passed to the Java Hotspot Virtual Machine. The options are aliased to -Xverify:all, -Xverify:remote, and -Xverify:none, respectively. These options, in turn, don't seem to be documented, at least not in the VM options documentation. [2] Ah, but they are documented elsewhere. [3] From that document: 8<-- So, why all this verification? When class files are loaded (possibly over the network or from an untrusted source) into a virtual machine, there is no way of telling how its byte codes were generated. Basically, in most cases, you can't trust the source of the Java class files. In fact, the default verification setting in JRE 1.1 is to only verify classes loaded from over the network. So, anything installed locally, via CLASSPATH, is not verified. In JRE 1.1, if you have installed something locally from a third-party and want to even verify that, too, you can do that. Or, you can completely disable verification. The three settings are all options to the java and jre commands: * -verifyremote - only perform verification process on classes loaded over network (default) * -verify - verify everything * -noverify - verify nothing In JDK 1.2, the default setting for verification is the same only verify classes loaded over the network. However, the system classes are specified from something other than the CLASSPATH environment variable, and the command line options for verification differ. The system classes are specified by either the System property sun.boot.class.path or the command line option -Xbootclasspath:directories and jar files. This is automatically set for you by the JRE and should never need to be set manually. If you set it to add something yourself be sure to include the original defaults, too. With regards to verification, if you wish to manually control the level of verification, the options to the java command with the V1.2 JRE are as follows: * -Xverify:remote - only perform verification process on classes loaded over network (default) * -Xverify:all - verify everything * -Xverify:none - verify nothing If a verification error is encountered, instead of the JRE reporting a verification error or throwing an exception, it reports a can't find error, like: Can't find class MyClass. 8<-- On the other hand, this message from the java-security mailing list archives [4] (from July 2001) seems to say something else: 8<-- The "system classes" such as those in java.* that are contained in rt.jar are loaded by the bootstrap class loader built-in to the Java Virtual Machine. In Jave 2, the next class loader searched for classes is the extension class loader which looks for classes in the jar files in the lib/ext directory where the Java Runtime Environment is installed. The so-called "system class loader" actually loads the application classes found from the -classpath command line argument or the CLASSPATH environment variable. Yes, the name "system class loader" is confusing. It is named that way for historical reasons when both core system classes as well as application classes were all loaded by the bootstrap class loader in JDK 1.1. > > I thought that, by default, the Java API classes (rt.jar) are the only ones > that dont go thru the ByteCode Verifier? You are correct again. By default, all classes go through the bytecode verifier except for those loaded by the bootstrap class loader. You can change this behavior through the use of command line arguments. This is because all classes except for those loaded by the bootstrap class loader can by granted fine-grained security permissions. In order to prevent those classes from cheating and trying to get more permissions than they have been granted we need to verify them. Classes loaded by the bootstrap class loader are always granted "AllPermission" and cannot be granted fewer permissions. These classes are trusted as part of the
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
> $ java -cp . -noverify HelloWorld > # > # An unexpected error has been detected by HotSpot Virtual Machine: > # > # EXCEPTION_ACCESS_VIOLATION (0xc005) at pc=0x6d7415fb, > pid=3512, tid=2260 # # Java VM: Java HotSpot(TM) Client VM > (1.5.0_06-b05 mixed mode) # Problematic frame: > # V [jvm.dll+0x615fb] Note that EXCEPTION_ACCESS_VIOLATION is the Windows equivalent of a segmentation violation; this isn't the Verifier complaining, it's the JVM crashing. The fact that editing the .class file allows you to produce one that causes the JVM to crash is pretty strong evidence the verifier was NOT used to validate the file. Tim Hollebeek Research Scientist Teknowledge Corp. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
I'm psyched about this thread. Rock on guys. For those of you who may need some basics, you might want to read Securing Java (a book I wrote with Ed Felten in 1999...the first edition in 1996 was called Java Security). The book is available completely for free in searchable format at http://www.securingjava.com I bring this up, because many of the terms being properly bandied about in this thread are carefully described there. Types, type confusion, the security model, the role of the verifier, why you can't trust byte code...etc. Happy history. I am feeling rather old. gem www.cigital.com/~gem www.swsec.com This electronic message transmission contains information that may be confidential or privileged. The information contained herein is intended solely for the recipient and use by any other party is not authorized. If you are not the intended recipient (or otherwise authorized to receive this message by the intended recipient), any disclosure, copying, distribution or use of the contents of the information is prohibited. If you have received this electronic message transmission in error, please contact the sender by reply email and delete all copies of this message. Cigital, Inc. accepts no responsibility for any loss or damage resulting directly or indirectly from the use of this email or its contents. Thank You. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Jeff Williams wrote: Two important clarifications for Java (based on my experiments): 1) The verifier IS enabled for the classes that come with the Java platform, such as those in rt.jar. So, for example, if you create a class that tries to set System.security (the private variable that points to the SecurityManager instance), you get a verification exception. (If this was possible, it would allow a complete bypass of the Java sandbox). But with either Type Confusion attacks or with the Security Manager disabled, you can still completely bypass the Java Sandbox, right? 2) The verifier also seems to be enabled for classes running inside Tomcat. I’m not sure about other J2EE containers. This is interesting, do you have any documentation to back this up? Ideally there would be a document somewhere which listed which J2EE containers run with the verifier on by default So I don’t think it’s fair to say that most Java code is running without verification. If all jsp out there is verified then yes 99% is not a correct number, any idea what percentage it could be? But Denis is right. There is a real problem with verification, as demonstrated in the message below. This is a clear violation of the Java VM Spec, yet my messages to the team at Sun developing the new verifier have been ignored. And it’s a real issue, given the number of applications that rely on libraries they didn’t compile. I don’t think a real explanation of how the Sun verifier actually works is too much to ask, given the risk. I agree, and Sun will probably do the same thing that Microsoft is doing at the moment: "Ignore the issue and hope that it goes away" Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Tim Hollebeek wrote: > The fact that editing the .class file allows you to produce one that > causes the JVM to crash is pretty strong evidence the verifier was > NOT used to validate the file. > Right. What follows is a summary of what we know so far, and what I think is going on. The details get a bit gory at the end, but you can skim it. I ran the corrupted .class file three ways, and obtained these results: 1) (no switch): ClassFormatError exception 2) -verify: ClassFormatError exception 3) -noverify: JVM crash (EXCEPTION_ACCESS_VIOLATION) I thought (incorrectly) that this might indicate that providing no switch was equivalent to -verify. In fact, it now appears that providing no switch is equivalent to -verifyremote (see my previous message). If I do the same experiment again, I see that, yes, "java -verify" and "java -verifyremote" produce the same result, and "java -noverify" crashes the JVM. This suggests to me that the locally loaded HelloWorld.class file is considered "remote" code. On the other hand, Michael's and Dinis's experiments show that (using Michael's example, after recompiling Foo.java once k is made a private member): 1) (no switch / -verifyremote ): illegal access to private member ALLOWED 2) -verify (i.e. -Xverify:all): illegal access to private member CAUGHT 3) -noverify( i.e. -Xverify:none): illegal access to private member ALLOWED So in this case, cases 1 and 3 are the same (with my mangled .class file experiment, cases 1 and 2 are the same). This suggests that the Foo.class file is being treated as "local" code. How are we to understand this? The short answer is that the meaning of "remote" depends on what type of verification Sun's hotspot VM is doing. With the help of Gary's book [1][2] (thanks!) we note that the Verifier, in verifying classes, performs two kinds of checks: "verification time" checks (steps 1-3 of page [2]) on the class file and its bytecodes, and "runtime" checks, checks that can't be done at verification time because "aspects of Java's type system cannot be statically checked." This includes "check[ing] the executing method for access privilege." This is step 4. on page [2] of Gary's book). We see that my experiment involves static, verification-time checks. Michael and Divis's experiments, on the other hand, involve runtime checks. It appears that the VM is treating .class files loaded through the CLASSPATH as "remote" for the purpose of verification-time (i.e. static) checks, but treating them as "local" for the purpose of run-time access checking verification. Just to verify this, here is another experiment, again with the corrupt class file (actually, this is the HelloWorld.class from my last email, so it's a slightly different ClassFormatError). First, I run with java -verifyremote and get the ClassFormatError. This means the VM thinks ./HelloWorld.class is remote. Next, I use the -Xbootclasspath/a switch to add the current directory to the bootclasspath. This should cause the VM to treat ./HelloWorld.class as it does the system classes in rt.jar, etc, i.e., "local." And, yes, now, I get the JVM crash, even with -verifyremote: ---8<-- $ java -verifyremote HelloWorld Exception in thread "main" java.lang.ClassFormatError: Invalid method Code length 858993413 in class file HelloWorld at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:620) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:260) at java.net.URLClassLoader.access$100(URLClassLoader.java:56) at java.net.URLClassLoader$1.run(URLClassLoader.java:195) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at java.lang.ClassLoader.loadClass(ClassLoader.java:306) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268) at java.lang.ClassLoader.loadClass(ClassLoader.java:251) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) $ java -Xbootclasspath/a:. -verifyremote HelloWorld # # An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_ACCESS_VIOLATION (0xc005) at pc=0x6d72dacf, pid=5168, tid=3576 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode) # Problematic frame: # V [jvm.dll+0x4dacf] # # An error report file with more information is saved as hs_err_pid5168.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # ---8<-- Summary of what I think happens, more or less, with the 1.5 JRE. 1. DEFINITIONS a) "Bootstrap Class": any class that was loaded by the "Primordial Class Loader." [3] (aka "bootstrap class loader.") Classes in the bootstrap classpath are one example (like classes in rt.jar). b) "O
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
Jim Halfpenny on the Webappsec list has discovered that BEA's JRockit JDK _does_ use verification by default, his complete post quoted below (the test was to access private methods on a class): Hi, BEA JRockit verifies by default and as far as I am aware does not offer a -noverify option. $ java -cp . verifytest2.Main java.lang.IllegalAccessError: getName at verifytest2/Main.()V(Main.java:???) at verifytest2/Main.main([Ljava/lang/String;)V(Main.java:12) Tested with JRockit 1.4.2_08. Regards, Jim Halfpenny ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
David Eisner wrote: > > What determines when access to a private member is illegal? Is it, in > fact, the bytecode verifier? Yes, it's done by the fourth pass of the verifier as described here: http://java.sun.com/sfaq/verifier.html#HEADING13 Interestingly, Sun have posted a contest to try and crack the new verifier in Mustang: https://jdk.dev.java.net/CTV/learn.html -- Stephen de Vries Corsaire Ltd E-mail: [EMAIL PROTECTED] Tel:+44 1483 226014 Fax:+44 1483 226068 Web:http://www.corsaire.com ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
An interesting experiment on cracking verifiers was performed about ten years ago by brian bershad at the university of washington. The paradigm used comparative testing on multiple verifiers to find discrepancies. This is covered in securing java as well. Funny how I became interested in software security because of java security. We're coming full circle. gem www.cigital.com/~gem www.swsec.com -Original Message- From: Stephen de Vries [mailto:[EMAIL PROTECTED] Sent: Fri May 05 10:06:36 2006 To: David Eisner Cc: 'Secure Coding Mailing List' Subject: Re: [SC-L] By default, the Verifier is disabled on .Net and Java David Eisner wrote: > > What determines when access to a private member is illegal? Is it, in > fact, the bytecode verifier? Yes, it's done by the fourth pass of the verifier as described here: http://java.sun.com/sfaq/verifier.html#HEADING13 Interestingly, Sun have posted a contest to try and crack the new verifier in Mustang: https://jdk.dev.java.net/CTV/learn.html -- Stephen de Vries Corsaire Ltd E-mail: [EMAIL PROTECTED] Tel:+44 1483 226014 Fax:+44 1483 226068 Web:http://www.corsaire.com ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php This electronic message transmission contains information that may be confidential or privileged. The information contained herein is intended solely for the recipient and use by any other party is not authorized. If you are not the intended recipient (or otherwise authorized to receive this message by the intended recipient), any disclosure, copying, distribution or use of the contents of the information is prohibited. If you have received this electronic message transmission in error, please contact the sender by reply email and delete all copies of this message. Cigital, Inc. accepts no responsibility for any loss or damage resulting directly or indirectly from the use of this email or its contents. Thank You. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Jeff Williams wrote: But Dinis is right. There is a real problem with verification, as demonstrated in the message below. This is a clear violation of the Java VM Spec, yet my messages to the team at Sun developing the new verifier have been ignored. And it’s a real issue, given the number of applications that rely on libraries they didn’t compile. I don’t think a real explanation of how the Sun verifier actually works is too much to ask, given the risk. And 9 days into this discussion, Sun's comment (or somebody from Sun) is still nowhere to be seen (Microsoft is not the online one MIA :). Anybody had any luck with their off list attempts to get a comment on this issue? What about the main Java Application Server developers? WebSphere , WebLogic, JBoss, Enhydra, Blazix, Resin, JOnAS etc... It is important that they participate in this discussion, because amongst other things I would like them to answer my next questions, which are: "What is the point of the verifier?' , 'Why use it? and 'What are the real security advantages of enabling the verifier if the code is executed in an environment with the security manager disabled?' So far we have identified several cases where: * the Java verifier is NOT enabled by default - Local code (i.e. loaded from the local system) * the Java verifier is enabled by default - classes that come with the Java platform - classes running inside Tomcat - classes running inside BEA WebLogic Given that the main attack vector (to exploit the lack of verification) is the same for all cases mentioned above (the attack vector being the injection of malicious Java code on the application being executed) then I would like to know the reason for the inconsistency? I also would like to ask if the following comments are correct: Option A) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled Option B) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled OR with the security manager disabled If not, what value should Option A and B be? 10%, 50%, 75? Thanks for your comments Best regards Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Stephen de Vries wrote: Java has implemented this a bit differently, in that the byte code verifier and the security manager are independent. So you could for example, run an application with an airtight security policy (equiv to partial trust), but it could still be vulnerable to type confusion attacks if the verifier was not explicitly enabled. To have both enabled you'd need to run with: java -verify -Djava.security.policy ... This is a very weird decision by the Java Architects, since what is the point of creating and enforcing a airtight security policy if you can jump strait out of it via a Type Confusion attack? In fact, I would argue that you can't really say that you have an 'airtight security' policy if the verifier is not enabled! Right? Is there a example out there where (by default) java code is executed in an environment with : * the security manager enabled (with a strong security policy) and * the verifier disabled Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
Dinis Cruz writes... > Stephen de Vries wrote: > > Java has implemented this a bit differently, in that the byte code > > verifier and the security manager are independent. So you could for > > example, run an application with an airtight security policy (equiv to > > partial trust), but it could still be vulnerable to type confusion > > attacks if the verifier was not explicitly enabled. To have both > > enabled you'd need to run with: > > java -verify -Djava.security.policy ... > This is a very weird decision by the Java Architects, since what is the > point of creating and enforcing a airtight security policy if you can > jump strait out of it via a Type Confusion attack? > > In fact, I would argue that you can't really say that you have an > 'airtight security' policy if the verifier is not enabled! > > Right? > > Is there a example out there where (by default) java code is > executed in an environment with : > > * the security manager enabled (with a strong security policy) and > * the verifier disabled Just a hunch, but I suspect that it was designed this way to support mobile code, or more specifically applets. There is a security manager enabled (policy not airtight though; see McGraw/Felten's book on the subject) with applets, and the byte code verifier only verifies *remotely* loaded classes, which are the only ones presumed to be hostile. Dumb assumption, I know, but initially applets ran so slow, Sun probably had little choice if they hoped to "sell" applets. Besides, back then most of the hostile code WAS coming from different attack vectors--infected floppies or ftp'ing / running infected code. AV software monitored that attack vector, but not executable code coming in via HTTP through your browser. (Many do today, though.) But the assumption Sun made back then was that all locally loaded classes could be trusted and therefore were type-safe. In retrospect, several wrong decisions were made regarding web security. (Don't even get me started on Radio-ActiveX! ;-) But as they say, backward compatibility is the curse of software design, so we probably are stuck with it. Fortunately the verifier is pretty simple to enable in Java. OTOH, coming up with a good security policy is not so easy. I've only done it twice and it's been a laborious process each time assuming you start with essentially a fail-safe "no permissions" approach and only add permissions as-needed. Anyway, I'd say that applets were probably what drove this security model. Curious that applets probably now comprise less than %1 of all Java code today. -kevin --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED] Phone: 614.215.4788 <... add your favorite pithy quote about hindsight here ...> This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
That's essentially correct kevin. The idea was to be able to run not remote, but untrusted code. Note that modern readers will understand that local code can be untrusted. There is a good picture of this in securing java. gem -Original Message- From: Wall, Kevin [mailto:[EMAIL PROTECTED] Sent: Mon May 08 19:17:22 2006 To: Dinis Cruz; Stephen de Vries Cc: Secure Coding Mailing List Subject:RE: [SC-L] By default, the Verifier is disabled on .Net and Java Dinis Cruz writes... > Stephen de Vries wrote: > > Java has implemented this a bit differently, in that the byte code > > verifier and the security manager are independent. So you could for > > example, run an application with an airtight security policy (equiv to > > partial trust), but it could still be vulnerable to type confusion > > attacks if the verifier was not explicitly enabled. To have both > > enabled you'd need to run with: > > java -verify -Djava.security.policy ... > This is a very weird decision by the Java Architects, since what is the > point of creating and enforcing a airtight security policy if you can > jump strait out of it via a Type Confusion attack? > > In fact, I would argue that you can't really say that you have an > 'airtight security' policy if the verifier is not enabled! > > Right? > > Is there a example out there where (by default) java code is > executed in an environment with : > > * the security manager enabled (with a strong security policy) and > * the verifier disabled Just a hunch, but I suspect that it was designed this way to support mobile code, or more specifically applets. There is a security manager enabled (policy not airtight though; see McGraw/Felten's book on the subject) with applets, and the byte code verifier only verifies *remotely* loaded classes, which are the only ones presumed to be hostile. Dumb assumption, I know, but initially applets ran so slow, Sun probably had little choice if they hoped to "sell" applets. Besides, back then most of the hostile code WAS coming from different attack vectors--infected floppies or ftp'ing / running infected code. AV software monitored that attack vector, but not executable code coming in via HTTP through your browser. (Many do today, though.) But the assumption Sun made back then was that all locally loaded classes could be trusted and therefore were type-safe. In retrospect, several wrong decisions were made regarding web security. (Don't even get me started on Radio-ActiveX! ;-) But as they say, backward compatibility is the curse of software design, so we probably are stuck with it. Fortunately the verifier is pretty simple to enable in Java. OTOH, coming up with a good security policy is not so easy. I've only done it twice and it's been a laborious process each time assuming you start with essentially a fail-safe "no permissions" approach and only add permissions as-needed. Anyway, I'd say that applets were probably what drove this security model. Curious that applets probably now comprise less than %1 of all Java code today. -kevin --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED] Phone: 614.215.4788 <... add your favorite pithy quote about hindsight here ...> This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php This electronic message transmission contains information that may be confidential or privileged. The information contained herein is intended solely for the recipient and use by any other party is not authorized. If you are not the intended recipient (or otherwise authorized to receive this message by the intended recipient), any disclosure, copying, distribution or use of the contents of the information is prohibited. If you have received this electronic message transmission in error, please contact the sender by reply email and delete all copies of this message. Cigital, Inc. accepts no responsibility for any loss or damage resulting directly or indirectly from the use of this email or its contents. Thank You. _
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 5/9/06, Dinis Cruz <[EMAIL PROTECTED]> wrote: Stephen de Vries wrote: > Java has implemented this a bit differently, in that the byte code > verifier and the security manager are independent. So you could for > example, run an application with an airtight security policy (equiv to > partial trust), but it could still be vulnerable to type confusion > attacks if the verifier was not explicitly enabled. To have both > enabled you'd need to run with: > java -verify -Djava.security.policy ... This is a very weird decision by the Java Architects, since what is the point of creating and enforcing a airtight security policy if you can jump strait out of it via a Type Confusion attack? In fact, I would argue that you can't really say that you have an 'airtight security' policy if the verifier is not enabled! You can't disable the security manager even with the verifier off. But you could extend some final or private class that the security manager gives access to. Is there a example out there where (by default) java code is executed in an environment with : * the security manager enabled (with a strong security policy) and * the verifier disabled Yes. Your local JRE. -- Michael ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 5/9/06, Dinis Cruz <[EMAIL PROTECTED]> wrote: Jeff Williams wrote: > > But Dinis is right. There is a real problem with verification, as > demonstrated in the message below. This is a clear violation of the > Java VM Spec, yet my messages to the team at Sun developing the new > verifier have been ignored. And it's a real issue, given the number of > applications that rely on libraries they didn't compile. I don't think > a real explanation of how the Sun verifier actually works is too much > to ask, given the risk. > And 9 days into this discussion, Sun's comment (or somebody from Sun) is still nowhere to be seen (Microsoft is not the online one MIA :). Anybody had any luck with their off list attempts to get a comment on this issue? What about the main Java Application Server developers? WebSphere , WebLogic, JBoss, Enhydra, Blazix, Resin, JOnAS etc... It is important that they participate in this discussion, because amongst other things I would like them to answer my next questions, which are: "What is the point of the verifier?' , 'Why use it? and 'What are the real security advantages of enabling the verifier if the code is executed in an environment with the security manager disabled?' Huh? You can find what it does here: http://java.sun.com/sfaq/verifier.html The security manager and the verifier are different. The security manager allows you to restrict runtime-knowledge type things. Connecting a socket, opening a file, exiting the vm, and so on. The verifier deals with other things. As you know, right? So far we have identified several cases where: * the Java verifier is NOT enabled by default - Local code (i.e. loaded from the local system) * the Java verifier is enabled by default - classes that come with the Java platform - classes running inside Tomcat - classes running inside BEA WebLogic Given that the main attack vector (to exploit the lack of verification) is the same for all cases mentioned above (the attack vector being the injection of malicious Java code on the application being executed) then I would like to know the reason for the inconsistency? I also would like to ask if the following comments are correct: Option A) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled Option B) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled OR with the security manager disabled I'd say no. We already know BEA/Tomcat/(And from my knowledge Websphere) all run with verification ON by default. All these 3 don't take up only "1%" of all java code. If not, what value should Option A and B be? 10%, 50%, 75? Download the app servers and check the documentation? I'd guess most have it on by default. Not off. Just my guess though ... -- Michael ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
The switch from "applets vs applications" security to "trusted code vs untrusted code" happened with the introduction of jdk 1.1 (way back when). Ed and I followed the sun marketing lead in 96 when it came to applets vs applications, but we cleared this up later in Securing Java www.securingjava.com. gem www.swsec.com -Original Message- From: Wall, Kevin [mailto:[EMAIL PROTECTED] Sent: Mon May 08 19:17:22 2006 To: Dinis Cruz; Stephen de Vries Cc: Secure Coding Mailing List Subject: RE: [SC-L] By default, the Verifier is disabled on .Net and Java Dinis Cruz writes... > Stephen de Vries wrote: > > Java has implemented this a bit differently, in that the byte code > > verifier and the security manager are independent. So you could for > > example, run an application with an airtight security policy (equiv to > > partial trust), but it could still be vulnerable to type confusion > > attacks if the verifier was not explicitly enabled. To have both > > enabled you'd need to run with: > > java -verify -Djava.security.policy ... > This is a very weird decision by the Java Architects, since what is the > point of creating and enforcing a airtight security policy if you can > jump strait out of it via a Type Confusion attack? > > In fact, I would argue that you can't really say that you have an > 'airtight security' policy if the verifier is not enabled! > > Right? > > Is there a example out there where (by default) java code is > executed in an environment with : > > * the security manager enabled (with a strong security policy) and > * the verifier disabled Just a hunch, but I suspect that it was designed this way to support mobile code, or more specifically applets. There is a security manager enabled (policy not airtight though; see McGraw/Felten's book on the subject) with applets, and the byte code verifier only verifies *remotely* loaded classes, which are the only ones presumed to be hostile. Dumb assumption, I know, but initially applets ran so slow, Sun probably had little choice if they hoped to "sell" applets. Besides, back then most of the hostile code WAS coming from different attack vectors--infected floppies or ftp'ing / running infected code. AV software monitored that attack vector, but not executable code coming in via HTTP through your browser. (Many do today, though.) But the assumption Sun made back then was that all locally loaded classes could be trusted and therefore were type-safe. In retrospect, several wrong decisions were made regarding web security. (Don't even get me started on Radio-ActiveX! ;-) But as they say, backward compatibility is the curse of software design, so we probably are stuck with it. Fortunately the verifier is pretty simple to enable in Java. OTOH, coming up with a good security policy is not so easy. I've only done it twice and it's been a laborious process each time assuming you start with essentially a fail-safe "no permissions" approach and only add permissions as-needed. Anyway, I'd say that applets were probably what drove this security model. Curious that applets probably now comprise less than %1 of all Java code today. -kevin --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED] Phone: 614.215.4788 <... add your favorite pithy quote about hindsight here ...> This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments. ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php This electronic message transmission contains information that may be confidential or privileged. The information contained herein is intended solely for the recipient and use by any other party is not authorized. If you are not the intended recipient (or otherwise authorized to receive this message by the intended recipient), any disclosure, copying, distribution or use of the contents of the information is prohibited. If you have received this electronic message transmission in error, please contact the sender by reply email and delete all copies of this message. Cigital, Inc. accepts no responsibility for any loss or damage resulting directly or indirectly from the use of this email or its contents. Thank You. --
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Michael Silk wrote: > On 5/9/06, Dinis Cruz <[EMAIL PROTECTED]> wrote: > >> Is there a example out there where (by default) java code is executed in >> an environment with : >> >> * the security manager enabled (with a strong security policy) and >> * the verifier disabled > > Yes. Your local JRE. ...but only in the exceptional case where a local Java application was started with a security manager activated, but without the -verify flag enabled. Most local Java applications are started without the verifier enabled and without a security manager. For untrusted applets and webstart apps, both the verifier and a security manager are enabled. -- Stephen de Vries Corsaire Ltd E-mail: [EMAIL PROTECTED] Tel:+44 1483 226014 Fax:+44 1483 226068 Web:http://www.corsaire.com ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
RE: [SC-L] By default, the Verifier is disabled on .Net and Java
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). You're right -- I checked that too. So I think it's just too simple to talk about the verifier being either on or off. It appears to me that the verifier can be enabled for some code and not for other code. I think you're right that this behavior has something to do with the classloader that is used, but I'd really like to understand exactly what the rules are. --Jeff ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
The "verifier" is enabled via the commandline. It is either on or off. the VM does other forms of "verification" though. http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html#79383 ... -- Michael On 5/11/06, Jeff Williams <[EMAIL PROTECTED]> 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). You're right -- I checked that too. So I think it's just too simple to talk about the verifier being either on or off. It appears to me that the verifier can be enabled for some code and not for other code. I think you're right that this behavior has something to do with the classloader that is used, but I'd really like to understand exactly what the rules are. --Jeff ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Michael Silk wrote: > The "verifier" is enabled via the commandline. It is either on or off. I'm not sure that's true. See: http://securecoding.org/pipermail/sc-l/2006/000262.html Summary: there are *three* comandline options: -verify, -noverify, and -verifyremote. It is -verifyremote that is the default, which only verifies "remote" code. However, the definition of "remote" depends on which of the four phases [1] of verification are being performed. -David [1] http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#9766 ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Michael Silk wrote: You can't disable the security manager even with the verifier off. But you could extend some final or private class that the security manager gives access to. This is not correct. With the verifier disabled there are multiple ways you can jump out of the Security Manager Sandbox. Here is a quote from 1997's Java Security (Gary McGraw and Eduard W. Feltern) book, page 75, Chapter Three 'Serious Holes in the Security Model" "... The Type Confusion Tool Kit The Princeton team, as a feasibility demonstration, created a tool kit that allows any type confusion attack to be turned into a disarming of Java's security. In other words, the tool kit servers as a way of turning a small security breach into a complete system penetration. The type confusion tool kit has not been released to the public, and is considered to dangerous to describe in any detail here..." A variation of this quote can also at the bottom of this page: Section 7 -- You're Not My Type Another quote from Section 7 -- You're Not My Type "...As mentioned in Chapter 2, every aspect of Java security depends critically on the type-safety of the language. This means that if Java is going to be secure, it has to make sure that all pointers are properly tagged; that is, the tag must match the actual type of object that is being pointed to. In a type-confusion attack, a malicious applet creates two pointers to the same object-with incompatible type tags. When this happens, the Java system is in trouble. The applet can write into that memory address through one pointer, and read it through another pointer. The result is that the applet can bypass the typing rules of Java, completely undermining its security" The example that we have been playing around here (the direct access to a private member) is probably not the best one to use to test the verifier, since there are multiple ways that this type of illegal access can be 'accidentally' detected by the VM (in Java there are some cases where the class loading process detects this, and in .Net the JIT will catch it) I think that it will be better to use the examples shown in the brilliant LSD paper http://lsd-pl.net/papers.html#java or a variation of the ones I discovered in .Net: Possible Type Confusion issue in .Net 1.1 (only works in FullTrust) (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx) Another Full Trust CLR Verification issue: Exploiting Passing Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/393.aspx) Another Full Trust CLR Verification issue: Changing Private Field using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/2005/12/28/394.aspx) Another Full Trust CLR Verification issue: changing the Method Parameters order (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx) In fact, it would be great to have a 'verifier checker' tool. A set of scripts that would test for verifier issues on Java execution environments (this would make it very easy to detect who is using the verifier and what type of verification is performed). After this explanation, Stephen, do you still disagree with my original comments: "This is a very weird decision by the Java Architects, since what is the point of creating and enforcing a airtight security policy if you can jump strait out of it via a Type Confusion attack? In fact, I would argue that you can't really say that you have an 'airtight security' policy if the verifier is not enabled!" Best regards Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Tim Hollebeek wrote: $ java -cp . -noverify HelloWorld # # An unexpected error has been detected by HotSpot Virtual Machine: # # EXCEPTION_ACCESS_VIOLATION (0xc005) at pc=0x6d7415fb, pid=3512, tid=2260 # # Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode) # Problematic frame: # V [jvm.dll+0x615fb] Note that EXCEPTION_ACCESS_VIOLATION is the Windows equivalent of a segmentation violation; this isn't the Verifier complaining, it's the JVM crashing. Yes, I noticed that too, the byte manipulation created a situation that crashed the VM. Usually these type of errors are caused by Buffer Overflows, so this could be a good example of how -noverify java code can be used to take over the local JVM process Depending of where the exploit is placed, there is even a possibility that the Java ByteCode will not be affected (which would difficult the detection of this exploit by (for example) source code security analyzers). Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Michael Silk wrote: "What is the point of the verifier?' , 'Why use it? and 'What are the real security advantages of enabling the verifier if the code is executed in an environment with the security manager disabled?' Huh? You can find what it does here: http://java.sun.com/sfaq/verifier.html The security manager and the verifier are different. Of course they are, but it is pointless to have only ONE of them enabled. You need BOTH Security Manager and Verifier to start to have a Sandbox (and even then the Sandbox's security will depend on the security policies) The security manager allows you to restrict runtime-knowledge type things. Connecting a socket, opening a file, exiting the vm, and so on. Sure, but when you have a security policy that restricts access to sockets files, if the code you are trying to restrict is executed with -noverify, then there are ways around those restrictions and have 'unauthorized' access to those sockets or files. Given that the main attack vector (to exploit the lack of verification) is the same for all cases mentioned above (the attack vector being the injection of malicious Java code on the application being executed) then I would like to know the reason for the inconsistency? I also would like to ask if the following comments are correct: Option A) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled Option B) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled OR with the security manager disabled I'd say no. We already know BEA/Tomcat/(And from my knowledge Websphere) all run with verification ON by default. All these 3 don't take up only "1%" of all java code. Ok, but what about the security manager? I agree that in Option A) the value is not 99% (since the BEA/Tomcat/Webshepre code will take more that %1) But on Option B) (" Java code deployed to live systems is executed in an environment with the verifier disabled OR with the security manager disabled" ), which it the one that matters, we are still at 99% since the only code that falls outside that category (i.e. executed with the verifier AND the security manager enabled) is the mobile code which is executed under the default browser Java policies (we have to exclude the mobile Java code which requests and is granted more privileges). If not, what value should Option A and B be? 10%, 50%, 75? Download the app servers and check the documentation? I'd guess most have it on by default. Not off. Just my guess though ... Am I the only one that finds it surprising that such a pillar of Java Security is not properly known and information about 'who does what' doesn't seem to be readily available? Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Gary McGraw wrote: The switch from "applets vs applications" security to "trusted code vs untrusted code" happened with the introduction of jdk 1.1 (way back when). Ed and I followed the sun marketing lead in 96 when it came to applets vs applications, but we cleared this up later in Securing Java www.securingjava.com. well somebody at Java must have missed this memo (and in Microsoft too) since the only code that both Java and .Net don't trust is code executed from directly from the Internet into a Browser (and only if using the default policy, something that Microsoft with the 2.0 changes to the 'Click Once' system made very easy to bypass) Dinis Cruz Owasp .Net Project www.owasp.net ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 5/12/06, Dinis Cruz <[EMAIL PROTECTED]> wrote: Michael Silk wrote: "What is the point of the verifier?' , 'Why use it? and 'What are the real security advantages of enabling the verifier if the code is executed in an environment with the security manager disabled?' Huh? You can find what it does here: http://java.sun.com/sfaq/verifier.html The security manager and the verifier are different. Of course they are, but it is pointless to have only ONE of them enabled. No it isn't. You need BOTH Security Manager and Verifier to start to have a Sandbox (and even then the Sandbox's security will depend on the security policies) You can have a sandbox without the verifier. The security manager allows you to restrict runtime-knowledge type things. Connecting a socket, opening a file, exiting the vm, and so on. Sure, but when you have a security policy that restricts access to sockets files, if the code you are trying to restrict is executed with -noverify, then there are ways around those restrictions and have 'unauthorized' access to those sockets or files. How? Given that the main attack vector (to exploit the lack of verification) is the same for all cases mentioned above (the attack vector being the injection of malicious Java code on the application being executed) then I would like to know the reason for the inconsistency? I also would like to ask if the following comments are correct: Option A) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled Option B) 99% of the Java code deployed to live systems is executed in an environment with the verifier disabled OR with the security manager disabled I'd say no. We already know BEA/Tomcat/(And from my knowledge Websphere) all run with verification ON by default. All these 3 don't take up only "1%" of all java code. Ok, but what about the security manager? I agree that in Option A) the value is not 99% (since the BEA/Tomcat/Webshepre code will take more that %1) But on Option B) (" Java code deployed to live systems is executed in an environment with the verifier disabled OR with the security manager disabled" ), which it the one that matters, we are still at 99% since the only code that falls outside that category (i.e. executed with the verifier AND the security manager enabled) is the mobile code which is executed under the default browser Java policies (we have to exclude the mobile Java code which requests and is granted more privileges). Are you talking about java desktop applications now instead of j2ee websites? If so, then who cares? You'll be running inside a new vm. If not, what value should Option A and B be? 10%, 50%, 75? Download the app servers and check the documentation? I'd guess most have it on by default. Not off. Just my guess though ... Am I the only one that finds it surprising that such a pillar of Java Security is not properly known and information about 'who does what' doesn't seem to be readily available? What are you talking about? Documentation _is_ readily available and has been provided throughout this entire discussion. Dinis Cruz Owasp .Net Project www.owasp.net -- Michael ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 12 May 2006, at 09:10, Charles Miller wrote: It's not reflection: you're confusing IllegalAccessException and IllegalAccessError. For any non-Java nerd still listening in: there are two fundamental types of "Throwable" exception-conditions in Java: Exceptions and Errors[1]. Exceptions represent application-level conditions -- things an application is likely to be able to recover from, like network timeouts, trying to read beyond the end of a file, and so on. Errors, on the other hand, represent VM-level problems that an application can't really do anything about, like running out of memory, not finding a required native library, or encountering corrupted class files. IllegalAccessException happens when reflective code attempts to access some field or method it's not supposed to. Because it's a result of reflection, it's considered an application-level problem and it's assumed your code can recover gracefully. Amusingly enough, you can get around most IllegalAccessExceptions in java just by calling {field|method}.setAccessible(true). So long as there's no explicit SecurityManager installed, as soon as you've done that you're free to modify the field or call method to your heart's content[2]. IllegalAccess_Error_, on the other hand, happens when some non- reflective code issues a bytecode instruction that attempts to access a field or method it shouldn't be able to see. If you look at its class hierarchy, the meaning of the class is pretty clear: IllegalAccessError is a subclass of IncompatibleClassChangeError, which is a subclass of LinkageError. Because this is a problem at the bytecode/classloading level, and literally something that could happen on _any_ method-call or field-access, it's flagged as an error. The Error generally occurs when class A has been compiled against a version of class B where a method is public, but that method is private in the version of the same class it encounters at runtime. This sort of thing happens quite often in Java, you're frequently stuck in "jar file hell", in a twisty turny maze of library interdependencies, all with slightly different version numbers. More about the circumstances of IllegalAccessError here: http://java.sun.com/docs/books/vmspec/2nd-edition/html/ ConstantPool.doc.html Dynamic classloading isn't really at fault here. There are all sorts of pits you can fall into when you start rolling your own classloader (the Java webapp I develop supports dynamic runtime- deployable plugins, and the classloading issues are a HUGE headache), but IllegalAccessError isn't one of them. Charles [1] Exceptions are further divided into checked exceptions and runtime exceptions, but that's beyond the scope of this email [2] See also: http://www.javaspecialists.co.za/archive/ Issue014.html Thanks for clearing this up Charles. I've created another example that uses a class loader to load the classes, and this time, it throws an IllegalAccessError just like Tomcat does: Loading class: /Users/stephen/data/dev/classloader/myclass/ somepackage/MyTest.class Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ Runnable.class Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ Object.class Loading class: /Users/stephen/data/dev/classloader/myclass/ somepackage/MyData.class Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ System.class Exception in thread "main" java.lang.IllegalAccessError: tried to access method somepackage.MyData.getName()Ljava/lang/String; from class somepackage.MyTest at somepackage.MyTest.run(MyTest.java:15) at classloader.Main.main(Main.java:26) Java Result: 1 This error is thrown irrespective of the -verify flag. So it looks like using a classloader causes the VM to perform verification, whether or not the "verifier" was enabled. Michael Silk made a similar statement earlier in this thread. Would you agree? PoC code below: package classloader; public class Main { public Main() { } public static void main(String[] args) { //Illegal Access Error try { CustomLoader cl = new CustomLoader(System.getProperty ("user.dir")+"/myclass/"); Class myClass = cl.loadClass("somepackage.MyTest"); Runnable r = (Runnable)myClass.newInstance(); r.run(); } catch (Exception e) { e.printStackTrace(); } } } package classloader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class CustomLoader extends ClassLoader { private String path = null; public CustomLoader(String path) { this.path = path; } private byte[] getBytes( String filename ) throws IOException { File file = new File( filename ); long len = file.length(); byte raw[] = new byte[(int)len]; FileInputStream fi
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 12 May 2006, at 14:58, Dinis Cruz wrote: Michael Silk wrote: You can't disable the security manager even with the verifier off. But you could extend some final or private class that the security manager gives access to. This is not correct. With the verifier disabled there are multiple ways you can jump out of the Security Manager Sandbox. Here is a quote from 1997's Java Security (Gary McGraw and Eduard W. Feltern) book, page 75, Chapter Three 'Serious Holes in the Security Model" I'm a bit sceptical of this, I know Sun's track record on fixing JVM vulnerabilities hasn't always been great, but 9 years seems a bit excessive! Unfortunately the book doesn't provide any more details on the vulnerabilities so we're left guessing whether these still affect modern JVMs. Even with verification turned off with the - noverify option, I think it would be difficult to break out of a defined security manager. "... The Type Confusion Tool Kit The Princeton team, as a feasibility demonstration, created a tool kit that allows any type confusion attack to be turned into a disarming of Java's security. In other words, the tool kit servers as a way of turning a small security breach into a complete system penetration. The type confusion tool kit has not been released to the public, and is considered to dangerous to describe in any detail here..." A variation of this quote can also at the bottom of this page: Section 7 -- You're Not My Type Another quote from Section 7 -- You're Not My Type "...As mentioned in Chapter 2, every aspect of Java security depends critically on the type-safety of the language. This means that if Java is going to be secure, it has to make sure that all pointers are properly tagged; that is, the tag must match the actual type of object that is being pointed to. In a type-confusion attack, a malicious applet creates two pointers to the same object-with incompatible type tags. When this happens, the Java system is in trouble. The applet can write into that memory address through one pointer, and read it through another pointer. The result is that the applet can bypass the typing rules of Java, completely undermining its security" The example that we have been playing around here (the direct access to a private member) is probably not the best one to use to test the verifier, since there are multiple ways that this type of illegal access can be 'accidentally' detected by the VM (in Java there are some cases where the class loading process detects this, and in .Net the JIT will catch it) I think that it will be better to use the examples shown in the brilliant LSD paper http://lsd-pl.net/papers.html#java The paper mentions avenues of attack through vulnerabilities in Netscape 4.x's JVM and IE (Mirosoft's JVM). These are vulnerabilities in specific implementations of the JVM rather than inherent flaws in the JVM spec. Any type confusion attacks that are possible because of the lack of default verification (via -verify) in the JRE would affect the security of the users' own local code so it's unlikely that this will prove to be a practical attack vector, IMHO. or a variation of the ones I discovered in .Net: Possible Type Confusion issue in .Net 1.1 (only works in FullTrust) (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx) Another Full Trust CLR Verification issue: Exploiting Passing Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/ archive/2005/12/28/393.aspx) Another Full Trust CLR Verification issue: Changing Private Field using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/ 2005/12/28/394.aspx) Another Full Trust CLR Verification issue: changing the Method Parameters order (http://owasp.net/blogs/dinis_cruz/archive/ 2005/12/26/390.aspx) In fact, it would be great to have a 'verifier checker' tool. A set of scripts that would test for verifier issues on Java execution environments (this would make it very easy to detect who is using the verifier and what type of verification is performed). After this explanation, Stephen, do you still disagree with my original comments: "This is a very weird decision by the Java Architects, since what is the point of creating and enforcing a airtight security policy if you can jump strait out of it via a Type Confusion attack? This is speculation. We don't know if it's possible to break the security manager through a type confusion attack - the one reference we have is 9 years old and doesn't say much, the other targets specific implementation flaws older JVMs. Java verification and security has many layers (as we've seen in trying to pinpoint exactly when it happens!), so I don't think it's accurate to equate a lack of local code verification with a complete breakdown of the security manager - unless someone demonstrates otherwise. regards, Stephen
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Stephen, I think the reason you get the IllegalAccessError is because the VM thinks you are loading from a remote url. I don't think the user of a classloader per-se forces the verification of the class. (I wrote a class loader like yours that just loads a file with no package in the current dir and was able to access the private method). You can also note that your class isn't verified if -noverify is passed (perhaps this is obvious :) -- Michael On 5/13/06, Stephen de Vries <[EMAIL PROTECTED]> wrote: On 12 May 2006, at 09:10, Charles Miller wrote: > > It's not reflection: you're confusing IllegalAccessException and > IllegalAccessError. > > For any non-Java nerd still listening in: there are two fundamental > types of "Throwable" exception-conditions in Java: Exceptions and > Errors[1]. Exceptions represent application-level conditions -- > things an application is likely to be able to recover from, like > network timeouts, trying to read beyond the end of a file, and so > on. Errors, on the other hand, represent VM-level problems that an > application can't really do anything about, like running out of > memory, not finding a required native library, or encountering > corrupted class files. > > IllegalAccessException happens when reflective code attempts to > access some field or method it's not supposed to. Because it's a > result of reflection, it's considered an application-level problem > and it's assumed your code can recover gracefully. > > Amusingly enough, you can get around most IllegalAccessExceptions > in java just by calling {field|method}.setAccessible(true). So long > as there's no explicit SecurityManager installed, as soon as you've > done that you're free to modify the field or call method to your > heart's content[2]. > > IllegalAccess_Error_, on the other hand, happens when some non- > reflective code issues a bytecode instruction that attempts to > access a field or method it shouldn't be able to see. If you look > at its class hierarchy, the meaning of the class is pretty clear: > IllegalAccessError is a subclass of IncompatibleClassChangeError, > which is a subclass of LinkageError. Because this is a problem at > the bytecode/classloading level, and literally something that could > happen on _any_ method-call or field-access, it's flagged as an error. > > The Error generally occurs when class A has been compiled against a > version of class B where a method is public, but that method is > private in the version of the same class it encounters at runtime. > This sort of thing happens quite often in Java, you're frequently > stuck in "jar file hell", in a twisty turny maze of library > interdependencies, all with slightly different version numbers. > > More about the circumstances of IllegalAccessError here: > >http://java.sun.com/docs/books/vmspec/2nd-edition/html/ > ConstantPool.doc.html > > Dynamic classloading isn't really at fault here. There are all > sorts of pits you can fall into when you start rolling your own > classloader (the Java webapp I develop supports dynamic runtime- > deployable plugins, and the classloading issues are a HUGE > headache), but IllegalAccessError isn't one of them. > > Charles > >[1] Exceptions are further divided into checked exceptions and > runtime exceptions, but that's beyond the scope of this email >[2] See also: http://www.javaspecialists.co.za/archive/ > Issue014.html Thanks for clearing this up Charles. I've created another example that uses a class loader to load the classes, and this time, it throws an IllegalAccessError just like Tomcat does: Loading class: /Users/stephen/data/dev/classloader/myclass/ somepackage/MyTest.class Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ Runnable.class Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ Object.class Loading class: /Users/stephen/data/dev/classloader/myclass/ somepackage/MyData.class Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ System.class Exception in thread "main" java.lang.IllegalAccessError: tried to access method somepackage.MyData.getName()Ljava/lang/String; from class somepackage.MyTest at somepackage.MyTest.run(MyTest.java:15) at classloader.Main.main(Main.java:26) Java Result: 1 This error is thrown irrespective of the -verify flag. So it looks like using a classloader causes the VM to perform verification, whether or not the "verifier" was enabled. Michael Silk made a similar statement earlier in this thread. Would you agree? PoC code below: package classloader; public class Main { public Main() { } public static void main(String[] args) { //Illegal Access Error try { CustomLoader cl = new CustomLoader(System.getProperty ("user.dir")+"/myclass/"); Class myClass = cl.loadClass("somepackage.MyTest"); Runnable r = (Runnable)myClass.newInstance(); r.run(); } catch (Excepti
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Shall we ask ed felten to did out the old type confusion toolkit? gem -Original Message- From: Stephen de Vries [mailto:[EMAIL PROTECTED] Sent: Sat May 13 15:12:48 2006 To: Dinis Cruz Cc: Secure Coding Mailing List Subject:Re: [SC-L] By default, the Verifier is disabled on .Net and Java On 12 May 2006, at 14:58, Dinis Cruz wrote: > Michael Silk wrote: >> You can't disable the security manager even with the verifier off. >> But >> you could extend some final or private class that the security >> manager >> gives access to. > This is not correct. With the verifier disabled there are multiple > ways you can jump out of the Security Manager Sandbox. > > Here is a quote from 1997's Java Security (Gary McGraw and Eduard > W. Feltern) book, page 75, Chapter Three 'Serious Holes in the > Security Model" I'm a bit sceptical of this, I know Sun's track record on fixing JVM vulnerabilities hasn't always been great, but 9 years seems a bit excessive! Unfortunately the book doesn't provide any more details on the vulnerabilities so we're left guessing whether these still affect modern JVMs. Even with verification turned off with the - noverify option, I think it would be difficult to break out of a defined security manager. > > "... The Type Confusion Tool Kit The Princeton team, as a > feasibility demonstration, created a tool kit that allows any type > confusion attack to be turned into a disarming of Java's security. > In other words, the tool kit servers as a way of turning a small > security breach into a complete system penetration. The type > confusion tool kit has not been released to the public, and is > considered to dangerous to describe in any detail here..." > > A variation of this quote can also at the bottom of this page: > Section 7 -- You're Not My Type > > Another quote from Section 7 -- You're Not My Type > "...As mentioned in Chapter 2, every aspect of Java security > depends critically on the type-safety of the language. This means > that if Java is going to be secure, it has to make sure that all > pointers are properly tagged; that is, the tag must match the > actual type of object that is being pointed to. > > In a type-confusion attack, a malicious applet creates two pointers > to the same object-with incompatible type tags. When this happens, > the Java system is in trouble. The applet can write into that > memory address through one pointer, and read it through another > pointer. The result is that the applet can bypass the typing rules > of Java, completely undermining its security" > > The example that we have been playing around here (the direct > access to a private member) is probably not the best one to use to > test the verifier, since there are multiple ways that this type of > illegal access can be 'accidentally' detected by the VM (in Java > there are some cases where the class loading process detects this, > and in .Net the JIT will catch it) > > I think that it will be better to use the examples shown in the > brilliant LSD paper http://lsd-pl.net/papers.html#java The paper mentions avenues of attack through vulnerabilities in Netscape 4.x's JVM and IE (Mirosoft's JVM). These are vulnerabilities in specific implementations of the JVM rather than inherent flaws in the JVM spec. Any type confusion attacks that are possible because of the lack of default verification (via -verify) in the JRE would affect the security of the users' own local code so it's unlikely that this will prove to be a practical attack vector, IMHO. > or a variation of the ones I discovered in .Net: > > Possible Type Confusion issue in .Net 1.1 (only works in FullTrust) > (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx) > Another Full Trust CLR Verification issue: Exploiting Passing > Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/ > archive/2005/12/28/393.aspx) > Another Full Trust CLR Verification issue: Changing Private Field > using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/ > 2005/12/28/394.aspx) > Another Full Trust CLR Verification issue: changing the Method > Parameters order (http://owasp.net/blogs/dinis_cruz/archive/ > 2005/12/26/390.aspx) > In fact, it would be great to have a 'verifier checker' tool. A set > of scripts that would test for verifier issues on Java execution > environments (this would make it very easy to detect who is using > the verifier and what type of verification is performed). > > After this explanation, Stephen, do you still disagree with my > original comment
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Kevin is correct, a type confusion attack will allow the bypass of the security manager simply because via a type confusion attack you will be able to change what the security manager is 'seeing' In both .Net and Java, the sandboxes logic (CAS and Security manager) are external to the the JVM/CLR, that is the security checks ("can I access this file?", "do I have permissions to call this method?", etc...) are performed in the middle of the core Framework libraries. Basically what the core Framework developers do, is to analyze all public entry points, and make sure that all are protected with a Security Demand (using .Net terminology). These public methods will then call private methods, who will be the ones that actually access the resources being protected (note that in these private methods there are no security checks). So in an environment where you have a solid Security Policy (enforced by a Security Manager) but the verifier is NOT enabled, then to jump out of the sandbox all that you need to do is to create a Type Confusion exploit that allows you to access a private member that either: calls the protected resource directly or disables the Security Manager (which based on the description provided is the demo that I think Ed Felten did). Of course that there will be other ways to exploit a non-verify world. Without verification it should be possible to create Buffer Overflows and other types of direct manipulation of memory objects which all occur before the security manager has a change to do anything. Using a 'Matrix' Analogy, the Security Manager is the Police Department that operates inside the virtual world, where the verifier is the one that make sure that all characters (including the Police) behaves accordingly to the rules defined for that virtual world. In this analogy Neo (the hero) was able to perform several Type Safety or Verifier attacks which gave him those extra powers :) I will stick to my guns and say that in a Virtual Machine environment like the JVM or CLR it doesn't make sense to have the overhead of a security system (like CAS or Security Manager) if the verifier is disabled. Basically code executed with no verification is as 'secure' and contained as unmanaged code. And remember that this code will be able to access ALL resources that the account used to execute that code has (from emails to VPNs to documents to online financial services, etc...) But probably the best way forward (since the guys from SUN and other Java Application server can't be bothered (or don't have permission) to participate in this discussion) will be to do a proof of concept example. Why don't we do a 'break from a non verified Sandbox' challenge? Dinis Cruz Owasp .Net Project www.owasp.net Wall, Kevin wrote: Gary McGraw wrote... Shall we ask ed felten to did out the old type confusion toolkit? That might be a good idea, but depending on the exact exploits the 2 of you used, they may not work on JDK 1.5. However--and this is just a guess--that in principle, type confusion attacks could allow you to by-pass at least some of the SecurityManager permission checks, and so I agree that you really ought to have the verifier enabled if you are going to use the security manager. --- Kevin W. Wall Qwest Information Technology, Inc. [EMAIL PROTECTED] Phone: 614.215.4788 "The reason you have people breaking into your software all over the place is because your software sucks..." -- Former whitehouse cybersecurity advisor, Richard Clarke, at eWeek Security Summit -Original Message- From: [EMAIL PROTECTED] on behalf of Gary McGraw Sent: Sat 5/13/2006 4:42 PM To: Stephen de Vries; Dinis Cruz Cc: Secure Coding Mailing List Subject: Re: [SC-L] By default, the Verifier is disabled on .Net and Java Shall we ask ed felten to dig out the old type confusion toolkit? gem -Original Message- From: Stephen de Vries [mailto:[EMAIL PROTECTED]] Sent: Sat May 13 15:12:48 2006 To: Dinis Cruz Cc: Secure Coding Mailing List Subject: Re: [SC-L] By default, the Verifier is disabled on .Net and Java On 12 May 2006, at 14:58, Dinis Cruz wrote: Michael Silk wrote: You can't disable the security manager even with the verifier off. But you could extend some final or private class that the security manager gives access to. This is not correct. With the verifier disabled there are multiple ways you can jump out of the Security Manager Sandbox. Here is a quote from 1997's Java Security (Gary McGraw and Eduard W. Feltern) book, page 75, Chapter Three 'Serious Holes in the Security Model" I'm a bit sceptical of this, I know Sun's track record on fixing JVM vulnerabilities hasn't always been great, but 9 years seems a bit excessive! Unfortunately the book doesn
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
On 5/14/06, Dinis Cruz <[EMAIL PROTECTED]> wrote: Kevin is correct, a type confusion attack will allow the bypass of the security manager simply because via a type confusion attack you will be able to change what the security manager is 'seeing' In both .Net and Java, the sandboxes logic (CAS and Security manager) are external to the the JVM/CLR, that is the security checks ("can I access this file?", "do I have permissions to call this method?", etc...) are performed in the middle of the core Framework libraries. Basically what the core Framework developers do, is to analyze all public entry points, and make sure that all are protected with a Security Demand (using .Net terminology). These public methods will then call private methods, who will be the ones that actually access the resources being protected (note that in these private methods there are no security checks). So in an environment where you have a solid Security Policy (enforced by a Security Manager) but the verifier is NOT enabled, then to jump out of the sandbox all that you need to do is to create a Type Confusion exploit that allows you to access a private member that either: calls the protected resource directly or disables the Security Manager (which based on the description provided is the demo that I think Ed Felten did). Of course that there will be other ways to exploit a non-verify world. Without verification it should be possible to create Buffer Overflows and other types of direct manipulation of memory objects which all occur before the security manager has a change to do anything. Please read the java documentation. http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#40222 Maybe you are also interested in BCEL by apache. Using a 'Matrix' Analogy, the Security Manager is the Police Department that operates inside the virtual world, where the verifier is the one that make sure that all characters (including the Police) behaves accordingly to the rules defined for that virtual world. In this analogy Neo (the hero) was able to perform several Type Safety or Verifier attacks which gave him those extra powers :) I will stick to my guns and say that in a Virtual Machine environment like the JVM or CLR it doesn't make sense to have the overhead of a security system (like CAS or Security Manager) if the verifier is disabled. Basically code executed with no verification is as 'secure' and contained as unmanaged code. What do you mean by verification? And remember that this code will be able to access ALL resources that the account used to execute that code has (from emails to VPNs to documents to online financial services, etc...) But probably the best way forward (since the guys from SUN and other Java Application server can't be bothered (or don't have permission) to participate in this discussion) will be to do a proof of concept example. Why don't we do a 'break from a non verified Sandbox' challenge? "We" ? Why don't _YOU_ do it. This is your crusade. Your code must break out of a "-noverify" sandbox, but fail to break a -verifiy sandbox. Dinis Cruz Owasp .Net Project www.owasp.net -- Michael ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [SC-L] By default, the Verifier is disabled on .Net and Java
| Kevin is correct, a type confusion attack will allow the bypass of the | security manager simply because via a type confusion attack you will be able | to change what the security manager is 'seeing' | | So in an environment where you have a solid Security Policy (enforced by a | Security Manager) but the verifier is NOT enabled, then to jump out of the | sandbox all that you need to do is to create a Type Confusion exploit that | allows you to access a private member that either: calls the protected | resource directly or disables the Security Manager (which based on the | description provided is the demo that I think Ed Felten did) | | I will stick to my guns and say that in a Virtual Machine environment like | the JVM or CLR it doesn't make sense to have the overhead of a security | system (like CAS or Security Manager) if the verifier is disabled This is taking a bit too extreme a point of view. The issue here is what's trusted, and for what purpose. *Something* has to be trusted. The verifier, the security manager, the JVM - if you can't trust these, you have no hope. The Java/.Net defaults explicitly say: (a) I trust the compiler not to generate dangerous code; (b) I trust the local user not to put stuff on the local disk where it can be executed unless it came from the compiler and he trusts it; (c) I trust the OS to protect the stuff on the local disk. On the other hand, I *don't* trust stuff that comes off the network. Given the realities of the last 10 years of virus-like attacks, this trust model may well be questionable. But keep in mind that just because a Java application passes every verification and is acceptable to even a very strict security policy doesn't mean it isn't a trojan horse at a higher semantic level! Verifying bytecodes certainly blocks many attack vectors, and is a fine idea - but things are not all black and white. Runtime checking will inherently cost you performance. Someone will always have an application where the extra cost is "too high" relative to the risk of running unverified. Rather than absolute statements about requiring verification for all user-written code - while leaving it off for the large volume of system-provided code - we need a more nuanced view, a better way to quantify risks and costs and trade them off. Otherwise, the same forces that to this day argue that Java is unacceptable because of the overhead of garbage collection will continue to push for writing in completely unsafe languages. -- Jerry ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php
Re: [Owasp-dotnet] Re: [SC-L] By default, the Verifier is disabled on .Net and Java
Two important clarifications for Java (based on my experiments): 1) The verifier IS enabled for the classes that come with the Java platform, such as those in rt.jar. So, for example, if you create a class that tries to set System.security (the private variable that points to the SecurityManager instance), you get a verification exception. (If this was possible, it would allow a complete bypass of the Java sandbox). But with either Type Confusion attacks or with the Security Manager disabled, you can still completely bypass the Java Sandbox, right? 2) The verifier also seems to be enabled for classes running inside Tomcat. I'm not sure about other J2EE containers. This is interesting, do you have any documentation to back this up? Ideally there would be a document somewhere which listed which J2EE containers run with the verifier on by default So I don't think it's fair to say that most Java code is running without verification. If all jsp out there is verified then yes 99% is not a correct number, any idea what percentage it could be? But Denis is right. There is a real problem with verification, as demonstrated in the message below. This is a clear violation of the Java VM Spec, yet my messages to the team at Sun developing the new verifier have been ignored. And it's a real issue, given the number of applications that rely on libraries they didn't compile. I don't think a real explanation of how the Sun verifier actually works is too much to ask, given the risk. I agree, and Sun will probably do the same thing that Microsoft is doing at the moment: "Ignore the issue and hope that it goes away" I don't think so; they've got their Crack the Verifier initiative; and honestly, I don't think it's a big deal of verification isn't on by default on the desktop vm; when you double-click a jar it runs in a new vm, not with a current app you might also be running. As long as j2ee containers (tomcat as Jeff says, websphere as I've heard, and BEA WebLogic as someone else suggested) all run with verification I don't think it's a big deal [but interesting to note], is it? FWIW I've seen this "issue" come up many many times in the java forums and it's never taken this track. It's interesting to see it develop this way ... -- Michael ___ Secure Coding mailing list (SC-L) SC-L@securecoding.org List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l List charter available at - http://www.securecoding.org/list/charter.php