Security Flaws in Microsoft Internet Explorer

We have found a number of flaws in the latest releases of Microsoft Internet Explorer 4.0 and 3.02. We have described these problems to Microsoft, and they have released a new version of their Java virtual machine that addresses some of the problems we have found.

Note that there are a few errors that, while they are not caught at link or load time, are caught as they occur during the execution of the applet. We consider such behaviour a weakness, because it is not clear whether the errors are intentionally being deferred to runtime or whether some general purpose mechanism is incidentally catching some side-effect of the error. Further, even if the error is currently being caught at runtime, it is quite likely that a future modification to the base software may assume that it is dealing solely with well-formed, safe Java code, and thus introduce security problems. Hence, we consider any failure of the verifier to reject illegal Java code a potential vulnerability.

Also note that some paragraph numbers are missing in the discussion below. They refer to previously labeled suspected flaws which are either currently under consideration, or which turned out to be quirks of our testing environment. We have retained the original labeling in order to simplify the association between flaws and example test cases.

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.


Security hole
Possible security hole

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.

2. It is possible for an applet to contain jumps to out-of-bounds addresses. An applet that can jump out of bounds of what has been determined to be safe may invoke services to which it does not have permission.

4. The verifier does not check certain instructions 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.

5. The argument count field specified in a method invocation may not match the method signature. JVM operations which rely on the count field specified by the invocation may be compromised.

8. Arrays can be allocated using NEW instead of ANEWARRAY. This is not caught statically, but is caught at runtime. Allowing NEW to name arrays is a divergence from the Java Machine Specification.

12. 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. Reportedly, the current Microsoft compiler will silently ignore unreachable code.

13. It is possible for a method to exceed its stated maximum stack depth. An applet that exceeds the maximum stack depth in an undetectable manner poses security risks.

14. A field of a class can simultaneously be both protected and private. This is presumably allowed for backward compatibility, though the JVM specification disallows such fields.

15. Constant attributes can be assigned to non-static fields. 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.

16. 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.

17. Another internal length consistency in a class file is not caught. An internal length inconsistency may cause the JVM to perform an illegal operation.

18. Class namespace management may be confused by malformed class names. Correct, predictable namespace management is crucial to the safe execution of a JVM.

19. UTF8 strings may contain bytes in the range 0xf0 through 0xff . The JVM specification prohibits these bytes from appearing in UTF8 strings, but the verifier does not reject class files containing offending strings.

20. The ranges of code protected by exception handlers may overlap. The JVM definition is ambiguous when it comes to the treatment of such exception handlers, and this could lead to incompatibilities between different Java versions. While the JVM specification explicitly states that the overlap is not checked, we believe that the lack of checking will result in incompatible Java clients and applets with unpredictable behaviour.

21. 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.

23. The verifier does not catch illegal field names which contain non-ASCII characters. According to the JVM specification, field names are restricted to the set of ASCII characters. This restriction is not enforced.

24. The verifier does not catch illegal method names which contain non-ASCII characters. According to the JVM specification, method names are restricted to the set of ASCII characters. This restriction is not enforced.

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 & Brian Bershad

Project Kimera
Department of Computer Science and Engineering
© 1997, University of Washington