Security Flaws in SUN JDK 1.1.1 and 1.0.2
We have found twenty four flaws in Sun's Java bytecode verifiers 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.
Netscape Navigator Gold 3.01 on Suns and DEC Alphas exhibits all
twenty-four of the flaws in JDK 1.0.2 mentioned below. We have sample
applets for each flaw that pass Java safety and conformance
verification. All but one (Flaw #8, due to its nature, cannot possibly
be instantiated) of these fault containing applets are locally
instantiated and executed in the user's browser on those two
platforms.
The test results indicating problems in JDK 1.1.1 come from running
the standalone 1.1.1 verifier in the most secure manner possible, as
described to us by Sun. Fifteen of twenty-four flaws exist in JDK
1.1.1. 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.
Sun has posted a
clarification
regarding their response to our work.
Legend
|
Security hole
|
|
Possible security hole
|
|
Weakness/Divergence from the specification
|
|
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.
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. Java's safety relies on the fact that
all accesses are strongly-typed. To guard this, there are numerous
safety checks that are performed for each access which make sure
that, for instance, a field designated to hold a string object
only has strings assigned to it. There is, however, a flaw in
one part of the Java virtual machine that enables applets to
assign a long or double value into an object reference.
This enables an applet to create forged pointers to any information
within the system.
We have constructed a sample applet that exploits this flaw
and creates forged pointers to private information in a JVM.
Javasoft's JDK 1.0.2 on all platforms and Netscape's Navigator
Gold 3.01 (and earlier versions) on the Sun and Alpha
platforms exhibit this flaw.
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.
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.
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. Consequently, it is possible to create free-floating
mistyped data on the Java operand stack.
While we have not come up with a way to exploit this hole,
we are concerned that the interaction of this flaw with JIT
compilation has security ramifications. This flaw exists in
JDK 1.0.2 and Netscape Gold 3.01 (and earlier versions) on
Suns and Alphas.
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.
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. Reading past the end of a submitted
class file enables an applet to probe for information that
happened to be stored at that location.
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.
7. A class may simultaneously be an interface and final.
This flaw exists in JDK 1.0.2.
8. A method may simultaneously be Abstract & Final.
This flaw exists in JDK 1.1.1 as well as JDK 1.0.2.
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.
10. A method may simultaneously be Protected & Private.
This flaw exists in JDK 1.1.1 and JDK 1.0.2.
11. A method may simultaneously be Synchronized & Abstract.
This flaw exists in JDK 1.1.1 as well as JDK 1.0.2.
12. A method may simultaneously be Static & Abstract.
This flaw exists in JDK 1.1.1 as well as JDK 1.0.2.
13. A field may simultaneously be Protected & Private.
This flaw exists in JDK 1.1.1 as well as JDK 1.0.2.
14. A field may simultaneously be Final & Volatile.
This flaw exists in JDK 1.1.1 as well as JDK 1.0.2.
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.1.1 as well as JDK 1.0.2.
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.
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.
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.
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.
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.
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.
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.
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.
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 &
Brian Bershad