[Image] Security Flaws in SUN JDK 1.1.1 and 1.0.2 ---------------------------------------------------------------------------- We have found a number of flaws with Sun's Java bytecode verifier in JDK versions 1.1.1 and 1.0.2. The verifier is the piece of software that inspects untrusted, foreign, or potentially malicious code and decides whether it is safe to admit it into a user's computer. Certain flaws in the verifier may allow malicious applets to gain control of a user's computer. Some flaws are currently benign, but they point to a divergence from the Java virtual machine specification that could cause security holes as the software is modified in the future. This list of flaws is by no means exhaustive. Our testing methodology, combined with our secure verifier, allows us to continually and automatically test for flaws in commercial Java implementations. Our disassembler helps us easily examine the flaws uncovered by automatic testing. There are numerous categories of flaws that this list does not cover. We will be examining those categories in detail as we develop our verifier and overall research platform. The test results indicating problems in JDK1.0.2 come from running "javap -verify" on DEC Alphas, and may or may not indicate problems in JDK 1.0.2 based Java as used in browsers and other Java-enabled software. Sun's verifier performs a number of different checks based on the method of invocation. We learned from Sun after conducting our tests that "javap -verify" is not a reliable method of checking the safety of applets. The test results indicating problems in JDK 1.1.1 come from running the 1.1.1 verifier in the most secure manner possible, as described to us by Sun. Overall, we are concerned that there are so many different ways to invoke, and therefore test, verification. The test run that produced these flaws was made on April 23, 1997. The test suite at that time consisted of a few thousand mutated class files that exercised about 75% of the axioms in our verifier. Legend [Image] Security hole [Image] Possible security hole [Image] Weakness [Image] Ambiguity ---------------------------------------------------------------------------- TYPESAFETY ERRORS Java security depends on type-safety. Lapses in checking incoming applets for type-safety may allow rogue applets to gain access to private information or to invoke services to which they do not have permission. [Image] 1. It is possible to convert any number into a pointer to any object in the JVM, enabling rogue clients to gain access to priviledged information in Java virtual machines or otherwise force the JVM to perform an illegal operation. There is a type-loophole that enables applets to assign a long or double value into an object reference. This enables an applet to manufacture a pointer to any information within the system. We were able to exploit this flaw under JDK1.0.2 to gain access to any object in a Java Virtual Machine. This bug has been fixed in JDK 1.1.1, though it seems to exist in the DEC Alpha and Sun ports of Netscape Navigator Gold 3.01. [Image] 2. An exception descriptor in a Java class file may be invalid. An invalid descriptor could crash the JVM, or otherwise force it to perform an illegal operation. This flaw exists in JDK 1.0.2. [Image] 3. Thrown exception descriptors may be valid indices into the constant pool, but not of the correct type. An invalid descriptor could crash the JVM, or otherwise force it to perform an illegal operation. This flaw exists in JDK 1.0.2. [Image] 4. Typesafety of double and long operands may be compromised. A client can split longs and doubles on the operand stack. JVM needs to maintain the integrity of all data types on the Java operation stack. In particular, JVM should guarantee that long and double operands are not split by bytecode operations. However, in the case of one instruction, this check is not performed. This creates free-floating untyped data on the operand stack. While we have not come up with a way to exploit this hole, it is possible that the interaction of this flaw with JIT compilation has security ramifications. This flaw exists in JDK 1.0.2. [Image] 5. A method can declare its maximum number of locals (which include space for arguments) to be N, but take M arguments in its signature, where M can be greater than N. A virtual machine compiler or interpreter that relies solely on information mentioned in the maxlocals field could crash or otherwise be violated. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2, and prompted the security patch from Sun. [Image] 6. A certain internal length inconsistency in a class file is not caught. An internal length inconsistency may cause the JVM to perform an illegal operation. This flaw exists in JDK 1.1.1 and JDK 1.0.2. ACCESS FLAG CHECKS Java class methods and fields carry access information with them. Certain combinations of access flags are illegal, and need to be caught by the JVM. Illegal combinations of access flags could lead to safety violations or ambiguous execution. [Image] 7. A class may simultaneously be an interface and final. This flaw exists in JDK 1.0.2. [Image] 8. A method may simultaneously be Abstract & Final. This flaw exists in the JDK 1.1.1 verifier, though the error is caught at instantiation time. We consider the fact that the verifier does not catch this error a weakness. [Image] 9. A method may simultaneously be Native & Abstract. This flaw exists in the JDK 1.1.1 verifier, though the error is caught at instantiation time. We consider the fact that the verifier does not catch this error a weakness. [Image] 10. A method may simultaneously be Protected & Private. This flaw exists in JDK 1.1.1 and JDK 1.0.2. [Image] 11. A method may simultaneously be Synchronized & Abstract. This flaw exists in the JDK 1.1.1 verifier, though the error is caught at instantiation time. We consider the fact that the verifier does not catch this error a weakness. [Image] 12. A method may simultaneously be Static & Abstract. This flaw exists in the JDK 1.1.1 verifier, though the error is caught at instantiation time. We consider the fact that the verifier does not catch this error a weakness. [Image] 13. A field may simultaneously be Protected & Private. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2. [Image] 14. A field may simultaneously be Final & Volatile. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2. [Image] 15. Fields in interfaces may not be final. The JVM specification requires that all fields in interfaces be final. This flaw exists in JDK 1.0.2. [Image] 16. Non-static fields may take a constant attribute. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2. This is no longer in violation of the JVM specification due to an errata released on April 17, 1997. However, the verifiers tested, when released, were in violation of the JVM specification. [Image] 17. Access flags for some methods are unrestricted. Certain access methods on sensitive methods may enable clients to break the type-safety of the Java virtual machine. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2. INSTRUCTION AND CLASS FILE VALIDITY Java byte-code instructions need to conform to a standard format defined in the JVM specification. Failure to conform should be caught by the Java verifier. Any code that depends on unchecked assumptions about the bytecode can be made to crash. [Image] 18. The verifier does not check a certain instruction in the Java bytecode stream for proper conformance against the JVM specification. A virtual machine that assumed that the instruction stream is valid with regard to the JVM specification could be forced to perform illegal operations. This flaw exists in JDK 1.1.1. [Image] 19. The verifier does not check a certain instruction in the Java bytecode stream for proper conformance against the JVM specification. (This instruction is not the same one as described in 18). A virtual machine that assumed that the instruction stream is valid with regard to the JVM specification could be forced to perform illegal operations. This flaw exists in JDK 1.0.2. [Image] 20. Certain strings may contain illegal bytes. The JVM specification prohibits these bytes from appearing in such strings. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2. [Image] 21. The ranges of code protected by certain Java constructs can overlap. The JVM definition is ambiguous when it comes to the treatment of such constructs, and this could lead to incompatibilities between different Java versions. While the JVM book explicitly states that overlap is not checked, we believe that the lack of checking will result in incompatible Java clients and applets with unpredictable behaviour. This problem exists in JDK 1.1.1 as well as JDK 1.0.2. [Image] 22. The class file may contain unreachable code. While this does not immediately lead to an error, it is a weakness. A JIT compiler may attempt to compile the unreachable bytecode, whose safety is not verified. Assumptions in the compiler that the code is type-safe may be exploited to crash the JVM without executing the unreachable code. This flaw exists in JDK 1.1.1 as well as JDK 1.0.2. [Image] 23. The verifier does not catch another internal length inconsistency in an applet. Such inconsistencies, pads and gaps in the class file may be potential locations to attach viruses. This flaw exists in JDK 1.0.2. [Image] 24. Class namespace management may be confused by malformed class names. Correct, predictable namespace management is crucial to the safe execution of a JVM. This flaw exists in JDK 1.0.2. We have example applets for each of these flaws, and some links with which you can compare the output of the Kimera verifier to those of commercial Java virtual machines. However, we are distributing this information only to those with a need to know. Please contact us if you feel you should have access to bytecode samples, verifier output and the disassembly of the class files. ---------------------------------------------------------------------------- Emin Gün Sirer & Sean McDirmid & Brian Bershad Project Kimera Department of Computer Science and Engineering © 1997, University of Washington