Securing the Java Runtime Environment

When many business applications require multiple versions of Java, securing the Java Runtime Environment is of paramount importance.  This blog post forms part of a Java series including:

Java Deployment Rule Set and Active Directory Certificates

Java Deployment Rule Set and Self Signed Certificates

Java Runtime Environment (JRE) is used extensively in the enterprise for Rich Internet Applications (RIA) launched from the browser, and local Java-based desktop applications.

It’s difficult to support Java if every user has a different configuration, and coupled with this it’s not advisable to let users configure Java themselves due to the security implications.

Luckily its easy enough to lock down JRE settings with a few configuration files.

Securing the Java Runtime Environment

First start by creating the file: C:\Windows\Sun\Java\Deployment\deployment.config.  The file MUST exist in this location.  And paste and save the following inside the file:

deployment.system.config=file\:C\:/WINDOWS/Sun/Java/Deployment/deployment.properties
deployment.system.config.mandatory=true

The first setting points to the location of the deployment.properties file – this file will ultimately configure and lock down the Java settings.  We can store this file on a network but it’s advisable to keep it locally (see below), and due to it being a system-wide setting it should be in a per-machine location.  Hence for simplicity we keep it in the same location as the deployment.config file.

The second setting enforces that the deployment.properties file is used.  If the file cannot be located when mandatory is set to true (perhaps the file is stored on a network and the network location isn’t available) then Java will not load the application.

Create the deployment.properties file

Now we can start configuring and locking down the settings.  For JRE 7 (which is what we are locking down) we can see which Java settings are configurable.  Unfortunately not all settings are documented, but it’s a decent guide for most.

Create the file: C:\Windows\Sun\Java\Deployment\deployment.properties, then paste and save the following inside the file:

#*************************************
#************GENERAL TAB*************
#*************************************

deployment.proxy.type=PROX_TYPE_BROWSER
deployment.proxy.type.locked

deployment.javapi.cache.enabled=true
deployment.javapi.cache.enabled.locked

#*************************************
#************UPDATE TAB*************
#*************************************

deployment.expiration.check.enabled=false
deployment.expiration.check.enabled.locked

deployment.expiration.decision=NEVER
deployment.expiration.decision.locked

deployment.expiration.decision.suppression=true
deployment.expiration.decision.suppression.locked

deployment.javaws.autodownload=NEVER
deployment.javaws.autodownload.locked

#*************************************
#************SECURITY TAB*************
#*************************************

deployment.security.level=MEDIUM
deployment.security.level.locked

deployment.webjava.enabled=true
deployment.webjava.enabled.locked

deployment.user.security.exception.sites=C\:/WINDOWS/Sun/Java/Deployment/exception.sites
deployment.user.security.exception.sites.locked

#*************************************
#************ADVANCED TAB*************
#*************************************

#Start Debugging
deployment.trace=false
deployment.trace.locked
deployment.log=false
deployment.log.locked
deployment.javapi.lifecycle.exception=false
deployment.javapi.lifecycle.exception.locked
#End Debugging

#Start Java console
deployment.console.startup.mode=HIDE
deployment.console.startup.mode.locked
#End Java console

#Start Shortcut creation
deployment.javaws.shortcut=ASK_IF_HINTED
deployment.javaws.shortcut.locked
#End Shortcut creation

#Start JNLP File/MIME association
deployment.javaws.associations=ASSOCIATION_ASK_USER
deployment.javaws.associations.locked
#End JNLP File/MIME association

#Start Application installation
deployment.javaws.install=IF_HINT
deployment.javaws.install.locked
#End Application installation

#Start Secure environment execution
deployment.security.askgrantdialog.show=true
deployment.security.askgrantdialog.show.locked

deployment.security.sandbox.awtwarningwindow=true
deployment.security.sandbox.awtwarningwindow.locked

deployment.security.sandbox.jnlp.enhanced=true
deployment.security.sandbox.jnlp.enhanced.locked

deployment.security.clientauth.keystore.auto=true
deployment.security.clientauth.keystore.auto.locked

deployment.security.jsse.hostmismatch.warning=true
deployment.security.jsse.hostmismatch.warning.locked

deployment.security.https.warning.show=false
deployment.security.https.warning.show.locked
#End Secure environment execution

#Start Mixed code
deployment.security.mixcode=ENABLE
deployment.security.mixcode.locked
#End Mixed code

#Start Perform certificate revocation checks
deployment.security.revocation.check=ALL_CERTIFICATES
deployment.security.revocation.check.locked
#End Perform certificate revocation checks

#Start Check for certificate revocation - *bug* only locks if deployment.security.revocation.check=NO_CHECK
deployment.security.validation.crl=true
deployment.security.validation.crl.locked

deployment.security.validation.ocsp=true
deployment.security.validation.ocsp.locked
#End Check for certificate revocation

#Start Advanced security settings
deployment.security.browser.keystore.use=true
deployment.security.browser.keystore.use.locked

deployment.security.blacklist.check=true
deployment.security.blacklist.check.locked

deployment.security.password.cache=true
deployment.security.password.cache.locked

deployment.security.SSLv2Hello=false
deployment.security.SSLv2Hello.locked

deployment.security.SSLv3=true
deployment.security.SSLv3.locked

deployment.security.TLSv1=true
deployment.security.TLSv1.locked

deployment.security.TLSv1.1=false
deployment.security.TLSv1.1.locked

deployment.security.TLSv1.2=false
deployment.security.TLSv1.2.locked
#End Advanced security settings

#Start Miscellaneous
deployment.system.tray.icon=false
deployment.system.tray.icon.locked
#End Miscellaneous

Create the exception.sites file

Now create the file: C:\Windows\Sun\Java\Deployment\exception.sites.  This file can remain blank for now.  But adding application URLs to this list allows users to run RIAs that would normally be blocked by security checks.  An example of an entry in this file might be:

https://www.whatever.com:8443/

A limitation of this file is that it cannot accept wildcards.  I recently encountered an issue where a website would use a dynamic port range of around 20,000 ports!  So rather than add 20,000 rows to site.exceptions (not advisable!) I created a Java deployment ruleset with an Active Directory code signing certificate.  You can also create a Java deployment ruleset with a self signed certificate.  With the ruleset.xml file you can specify wildcards for the port in a single rule.

Disable updates via the registry

Finally there are a few registry values that we can, to prevent Java from automatically updating.  Bear in mind that this is for a 32-bit install of Java on a 64-bit platform, and hence the ‘Wow6432Node’ location:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\JavaSoft\Java Update\Policy]
"EnableJavaUpdate"=dword:00000000
"EnableAutoUpdateCheck"=dword:00000000
"NotifyDownload"=dword:00000000
"NotifyInstall"=dword:00000000

And finally, we’re done!

 

Java Network Settings and the Browser Proxy

Recently I spent a few days creating and compiling a Java Deployment Rule Set and signing it with an Active Directory certificate.  After much stress it worked like a charm on my development machine, but wasn’t working in production! And to discover why this was the case, we had to debug Java network settings and the browser proxy.

I tested some of my rules by using the Java verify page, whereby it displayed the version of Java that the browser was currently using.

However in the Live environment the Java verify page just wouln’t render the Java applet.  I added Java.com to the trusted sites zone, and then I got a grey box in place of the applet.

In the Java control panel I navigated to the Advanced tab and made sure to select ‘Show console’.  The next time I launched a new session of the Java verify page in Internet Explorer I could see what was happening:

Proxy Direct

I could see that the proxy was returning as: “proxy=DIRECT”.  This should not have been the case since we were using the default LAN Settings which was configured to use an Auto Config PAC file (a JavaScript file that says “if you’re navigating to this URL, use that proxy etc.).  So it should have been returning a valid proxy from the PAC file.

I changed my LAN setting to use a static proxy/port and re-ran the Java Verify page.  This time it worked and the console showed that it was returning a proxy address!

Since we’d deduced it wouldn’t work with the PAC file, one potential solution was to use Java network settings (Java control panel > General tab > Network settings) to point to a proxy, and leave the LAN settings as the auto config PAC file for all browing in Internet Explorer.  However when I tested this, once again I saw “proxy=DIRECT”!

Upon further testing I noticed that several versions of Java 7 ignore the Java Network Settings! These are:

Java 7u60
Java 7u67
Java 7u71
Java 7u72
Java 7u75

Finally these three versions honour the Network Settings, and the proxy was correctly used:

Java 7u76
Java 7u79
Java 7u80

But you’ll notice I did say that this was a ‘potential’ solution.  It still wasn’t an ideal solution.  Why wasn’t the auto config PAC file returning a valid proxy?  Well, I debugged our corporate PAC file and lo and behold, I noticed a missing semi-colon!

somevariable = “DIRECT”

should have been

somevariable = “DIRECT”;

So Internet Explorer parsed the PAC file ok, and ‘understood’ that there was a missing semi-colon and carried on routing users correctly when they were browsing the internet.  However Java’s parsing of the PAC file was obviously more strict, noticed a semi-colon was missing and consequently failed and reverted to a ‘DIRECT’ connection!  Once I fixed this issue Java in Internet Explorer burst in to life!