Duckware
 You are here: Duckware » Technology » Oracle's Java Security Clusterfuck   Contact us  
Oracle's Java Security Clusterfuck
(September 1, 2013; other vulnerabilities)

Oracle intentionally and needlessly breaks local file system Java Applets

UPDATE: 1/21/2014: Thanks for Christian Beilken for pointing out that Java 7 Update 51 silently fixes getCodeBase() and getDocumentBase() -- NULL is no longer returned! However, for us at Duckware, the damage inflicted upon Java by Oracle is done -- we killed off all of our Java applets and switched over to HTML5!

Executive Summary: Oracle's Java Security team is removing "file path" information from a locally run Java applet, busting the applet, citing security concerns. But removal of that information was a clusterfuck from day one, because "file path" information will always be available — no matter what is done to Java — via the web page the applet is in:
<html><body>
<!-- Oracle ignores that 'file path' info is a part of HTML -->
<script>document.write("HREF="+window.location.href)</script>
<!-- and INTENTIONALLY breaks this applet -->
<applet code="pmvr.class" width=800 height=600>
  <param name="pano" value="mypanorama.jpg"> <!--busted-->
  </applet>
</body></html>
Therefore, the removal of the information from Java was pointless (even if all file path information is removed from Java, the applet can always get it from the web page), ill-conceived, reckless (someone should be fired over this), and not even implemented properly (Oracle returns null even for an applet code signed with FULL access to the computer).

And to make matters far worse, if removal was due to actual real 'security' reasons, the Oracle Java security team is incompetent due to blatantly obvious (disclosed below) remaining "file path" information in Java. I am willing to bet that the person on the security team who pushed for this has NO legitimate (toy maybe, but not real world) Java Applet programming experience.

The Problem: In Java 7u25, Oracle returns null for an Applet's getCodeBase() (and in Java 7u40, getDocumentBase() also returns null) when the Applet is running from the local file system. And now Oracle is saying that any sandboxed Applet's (signed or not) that requires access to non-JAR resources CAN NOT access those resources via getCodeBase(), even if the applet is code signed with FULL access to the computer. [Source: 7u25-relnotes]
"Local Applets return NULL for codebase: Beginning with JDK 7u25, an applet's getCodeBase() method will return NULL when the applet is running from the local file system."
Yes, you read that correctly. A code-signed Applet with FULL access to the computer will have a getCodeBase() and getDocumentBase() that return NULL, likely breaking the applet (something that I have tested and verified). Because, as Oracle says, for 'security' reasons. That is downright malicious (or is that incompetent) behavior on the part of Oracle -- especially when this issue is marked as "WILL NOT FIX, intended behavior."

Quick tips for Java Applet developers: Visit bugreport.sun.com and file a bug report, citing this web page. Assume that both Applet.getCodeBase() and Applet.getDocumentBase() don't exist (they will return null). Assume that Class.getResource() does not exist (a security exception will be thrown because Java will not allow you access to resource URL's). You must place all possible files inside the JAR, and use the Class.getResourceAsStream() calls to access. If you need to access any files outside the JAR, Oracle has screwed you over — switch to HTML5.

Oracle did this intentionally: A posting from Oracle's Sandeep Konchady (Senior Software Manager and former member of the JSS security team at Sun Microsystems) on gmane.comp.java.openjdk.security.devel, states:
"The issue you are seeing is intended behavior. This was caused because of a vulnerability that was fixed in 7u25 in which which (sic) a getCodeBase call against all local applet/jnlp apps will return null."
But what vulnerability? We find out from Java Bug Database ID=8017250:
"The fix to have getCodeBase() return NULL for file applets is because it will expose local file system information (file path), which sandbox applets should not have access to it."
The Core Issue: Oracle is intentionally killing off the Java security sandbox under the pretense of improving security. Oracle's alternative to a null getCodeBase()? Code sign your Java applet and get FULL UNRESTRICTED ACCESS to the entire computer. [Source: Java Bug Database ID=8017250]
"if the resource is in arbitary (sic) location, not inside applet JAR, they should have other ways to get to that location, since it's not part of the applet resource anyway. (e.g user.home java system property, provided that their applet has all-permissions)"

The Oracle employee who made those comments should be put out to pasture for having such a narrow mind and grossly misunderstanding real-world Java Applets that are driven by end-user created data (therefore impossible to add ahead of time to the JAR). Like a panorama applet trying to access a user created panorama, mypanorama.jpg, disclosed at the top of this web page.
Oracle's security fix for a sandboxed applet that can see some path information — already available via the web page — is to break the applet, and then Oracle recommends that 'the fix' for the broken applet is to run the applet outside the sandbox (where the Applet has access to EVERYTHING on the computer) WTF! — Oracle is clearly trying to kill off the security sandbox.

The Implication for a Sandboxed local Applet: Since there is no codebase (it is NULL), the applet has no permission to access any local non-JAR resources (like a panorama viewer applet that needs to load a multi-node panorama script):
InputStream in=(new URL(getDocumentBase(),"script.txt")).openStream();
This worked fine under ALL prior versions of Java, all the way back to Java 1.0.2 (1996). But now, in 2013, after working for 17 years, Oracle is saying that code should no longer work. Here is that error that is now seen:
java.security.AccessControlException: access denied ("java.io.FilePermission" "C:\javatest\script.txt" "read")
Seeing the difference: So, to see what is going on, place Duckware's java version applet in a folder on your local computer, like c:\javatest\, and when run in Java 6 (left), this applet can access the codebase, but when run in Java 7u25, this (sandboxed) applet can NOT access the codebase:
Summary of Oracle's reason: So, Oracle is breaking sandboxed local file system applets, because Oracle claims the applets should not have access to local file path information, which Oracle says is a security risk -- even though that information is available to the web page running the applet (and hence, the applet).



The problem with Oracle's attitude: But the huge problem with Oracle's attitude is that "file path" information is available all over the place in Java (and elsewhere), not just from getCodeBase(). So Oracle changing only getCodeBase() is a huge security FAIL, showing a complete lack of understanding in how Java works...

Place One: It should be painfully obvious to any astute reader at this point (and any real Java Applet programmer), that getDocumentBase() also reveals "file path" information. It is incredibly hard to miss when both methods are right next to each other in the documentation (seen right). NOTE that Oracle has stated that it intends for that to return null as well in the future.
System.out.println( ""+getDocumentBase() );

displays:

file:/C:/javatest/javahelp.html
Place Two: The Applet classloader reveals "file path" information:
System.out.println( ""+getClass().getClassLoader() );

displays:

Applet2ClassLoader{[file:/C:/javatest/javahelp.jar, file:/C:/javatest/]}
Place Three: Before I realized that Oracle had made this change intentionally (I thought it was just a bug), I implemented my own new getCodeBase(), that works for me (the codebase applet tag is accessible to the Applet):
String s = getParameter("codebase");
System.out.println( ""+new URL(getDocumentBase(),(s!=null)?s:"."));


displays:

file:/C:/javatest/
Place Four: Ask HTML/Javascript for the file path information:
Object o = (JSObject.getWindow(this)).eval("window.location.href");
System.out.println( ""+o );


displays:

file:///C:/javatest/javahelp.html
Place Five: With Javascript in the HTML web page, document.write() the <applet> tag into the HTML, passing windows.location.href as an applet parameter, which the Applet can then obtain via a getParameter(). If you are using Oracle's deployJava.js (reference), this is as easy as adding "myurl:window.location.href" to the "parameters" list:
System.out.println( getParameter("myurl") );

displays:

file:///C:/javatest/javahelp.html
Place Six ... and other places: There are other ways of obtaining the "file path" information from Java that I have confirmed -- but those are being withheld because Oracle's incompetent decision-making can not be trusted. Java leaks "file path" information from many places.



The Oracle clusterfuck: Is Oracle's Java security team really that incompetent to not understand that:
  1. getDocumentBase() exists
  2. file path information exists elsewhere in Java Applets in many places
  3. that window.location.href exists; OUTSIDE of Java in the web page; something Oracle can never remove
Even if Oracle did (eventually) eliminate ALL "file path" information from Java, "file path" can ALWAYS be obtained via windows.location.href. So there is no point in denying access to something that is already fully open and available outside of Java, in the HTML web page! Pure silliness (and a fool's errand) on the part of Oracle.
So what if a sandboxed applet gets its hands on "file path" information. It can do nothing more with that information, than what the web page alone (without Java) can already do with that information!

In fact, Java can do FAR LESS with that information that what the web page can do with it. Believe me when I say that that any local web page being viewed, without any applet, can already remotely record the entire local file path of the web page. So if there is any security threat here, it comes NOT from Java, but from the web page itself.
Exposing file path information to Java, exposes NO MORE information than what is already exposed to JavaScript inside the web page itself. Plugging all of Java does nothing to plug window.location.href inside the web page, and a web page is REQUIRED to run the applet. And in fact, Oracle requires Javascript to be enabled when using Oracle's preferred deployJava.js to deploy applets.

Draconian thinking: Oracles says, 'we can't expose file path information, so we are going to kill all file access' -- rather than thinking how they could continue to provide file access to file-based applet resources without file path information!

Conclusion: Oracle needlessly broke file system sandboxed applets, under the ridiculous guise of 'security', over something openly available to the web page. If 'security' was the true reason, the Oracle Java security team is incompetent and someone should be fired. Regardless of a sandbox or not, "file path" information is always available to the applet (via the webpage). Oracle needs to acknowledge that and restore getCodeBase() and getDocumentBase().

Oracle needs to IMMEDIATELY own up to their clusterfuck, and fix Java Applets ASAP.


ALTERNATIVE SANDBOX SOLUTIONS FOR ORACLE:

(1) BEST / A little work: The "file://" syntax already has a 'host' component. In a sandbox, the 'host' is meaningless, so use that! getCodeBase() should return "file://codebase#/" (where # is a unique number that identifies a particular JAR in use, of many). And due to how the bases (code and document) work when run via a local file system, the getDocumentBase() must ALWAYS be based on that. For example getDocumentBase() might return "file://codebase1/one/tour/index.html" (because applets in sub folders of a tree may codebase back to the web server root). Then internally, at the very lowest level possible, there is a substitution for "codebase1" to the real location on the file system (for example: "c:\javatest") in a way that will not leak real "file path" out in thrown exceptions.

(2) GOOD / Almost no work: When run from the local file system, return "file://" URL's that are REAL (but symbolic links), and point to a location that is "well known" and discloses nothing of substance. For example, getCodeBase() returns "file:///c:/CAFEBABE/XYZ/", where CAFEBABE (or whatever name Oracle wants and creates on the fly) is a Java VM controlled folder, and XYZ is a symbolic link to the real location on the file system, c:\javatest\

(3) A bug to fix regardless: Allow developers to access known non-JAR resources via getResourceAsStream() calls -- because as of now, even that is improperly busted. getResourceAsStream("pano.jpg") should work, but does not. That is a bug. There is no "file path" information.


More Information: Here is more information on the issue: Once again, Oracle knows about this: Funny how Oracle keeps hitting my web pages within hours of the posting going live. Thanks to 148.87.67.207, 193.9.13.138, 193.9.13.139, 202.45.129.180, 148.87.67.203, 148.87.19.198, 137.254.4.8, 148.87.67.212 Are you going to act, or sit there looking dumbfounded?
My direct inquiries into Oracle have so far been met with silence.


History is repeating itself: This is not the first time that Sun (Oracle) has messed around with getCodeBase() and getDocumentBase(). Sun did it once before arond 2002 and then reversed their decision. Now isn't it interesting that the bug report can NOT be found in Oracle's current bug database? But, here it is archived.



Is Lax Quality Control at Oracle the problem? It is very clear that Java is going 'out the door' without any meaningful quality control and it is easy to prove. Take any Applet, and add the following line of code:
System.out.println( getClass().getResourceAsStream("index.html") );
Then code sign the applet JAR and run in an index.html web page, locally. You will obtain a security popup asking if you want to give the applet full unrestricted access to the computer. Answer yes. And when the above line of code is run, you will get this completely bogus security popup that "The Applet contains both signed and unsigned code":


If you press the 'Block' button, null will be printed. If you press "Don't block" button, something non-null will be printed.

There is nothing worse than false positives to erode security confidence and this security popup does that. Because accessing the same file a different way — "getDocumentBase().openStream()" — yields no security popups.

Or, is Java itself becoming self-aware and when it says "Java has discovered ... a security concern", is Java itself warning all of us that Java itself presents a "security problem"? Smile . . . . if you can.


Copyright © 2013-2024 Duckware