Originally posted at timboudreau.com
While chatting with Simon Phipps, I read through the Java security exploit that got so much attention this week - and the patches to fix it. For anyone interested, here's a quick'n'dirty analysis (scroll down for the detailed technical analysis):
A Summary In Layman's Terms
The security problem is that someone found a way to let an applet go hog-wild on your computer without your permission. It's not news because things going hog-wild on computers is news - any of the many thousands of viruses for Windows do that. It is news because Java's record on security has been very good, making this a nasty surprise.
Specifically what the exploit does is:
- Create an array of bytes which is Java bytecode - a chunk of Java
software that can be run. If that code runs without security checks, it
can wreak whatever havoc its author wants.
- Create a JMX server. JMX is a server-side technology for monitoring servers, which allows server software to provide
MBeans - little Java classes that let administrators monitor and remote-control their software on the server. The JMX server can be told to load a class by name - meaning it is designed (for good reason) to load a Java class it has never seen before by someone saying to it "Go find a class named MyServerThing and load it". This is the technique called "reflection".
- Tell the JMX server to load two classes which are part of an
runtime. Notably, if you're going to run a language like that and you
want it to be fast, you're going to want to actually generate Java code
on the fly and load that up and run it. So you're going to need a ClassLoader to do it. And sure enough, there is one.
- Call a chain of methods, using reflection and the relatively new MethodHandle
reflection object which lets you call ad-hoc methods - to get the JMX
bean loader to actually make an instance of the classloader for
- Once it's gotten the JMX server to create the
ClassLoaderwhich will load ad-hoc bytes, the security breach is accomplished. It calls
defineClass, whcih actually lets you pass in an array of bytes and get back a
Classobject (the final line of the exploit,
Class.newInstance()is actually gratuitous - the exploit could just be done in the class' initializer)
Reflection - the ability to poke around in and call code your program
didn't know about when it was compiled - is an old technology, and can
be secured. The thing that actually got exploited was a new addition to
the reflection API, which lets you call code in a new way - that is
what was used to bypass security checks.
very necessary both for interpreted languages to run better on a JVM and
for future features that will keep Java itself competitive.
There probably is something to worry about with
and the new invoke dynamic instruction, since it is a new way to call
any code anywhere in the JVM. On the other hand, there are a handful - a
small and finite number - of choke-points to intercept such an attack.
They are those calls that allow you to actually tell a JVM "these bytes
are Java code" and have it actually load them. If you secure that,
you've put most of the issue to bed. Java has had the ability to secure
that for many, many years, so it's reasonable to expect this particular
flavor of exploit to be locked down well and truly.
The fix released today fixes the immediate exploit. A proper fix would sit in the critical path between any code and
ClassLoader.defineClass(). It is reasonable to get a minimal fix out fast. Doing anything that touches the way every byte of Java code gets loaded is not
something you can do without heavy testing. So, kudos to Oracle for
quashing the immediate problem, and being conservative about what kind
of fix can be done quickly with low liklihood of unintended
consequences. But they should do a more thorough fix.
I agree with critics who say there are a lot of subsystems interacting here - pieces of applets, JMX and a scripting language interpreter were combined in a novel way to create an exploit.
I disagree with the critics who say that there is so much complex interplay that the problem will not give way to analysis without weeks or months of study. All you have to care about to fix something like this are the choke-points that any code which tries to load bytecode must pass through. This kind of apocalyptic punditry seems more like a way to simultaneously look good, make news and be intellectually lazy. We're talking about a finite amount of code well within the capacity of a capable programmer's understanding.
All That Being Said...
I smell a whiff of nasty industry politics in this. At least I suspect getting Homeland Security to announce "don't use Java" was a coup for somebody, who is celebrating a bonus or popping the cork on a champagne bottle or both. If a Java exploit is a national security threat, then considering the history of Windows and what virii have cost there, there ought to be an airlift of developers from Redmond to Gitmo in leg-irons.