Introducing Deployment Rule Sets

As the Java security model has hardened for browser-based applets, desktop administrators have asked for ways to manage version compatibility and security updates for their end-users.

A new feature is being introduced in Java 7 update 40 called “Deployment Rule Set,” designed to address the issue of security and compatibility in browser applets without affecting normal back-end Java programs like Eclipse, Freemind, or Tomcat. Specifically this deployment rule set addresses two major points:

  1. The desktop administrator’s ability to control Java version compatibility, and default choices on the end-user’s desktop. For example your users may use most recent security updates for most browser applets but still use an old Java 1.6 for that one legacy application that is no longer maintained.
  2. The end-user’s awareness of who created the application and their default interaction (ask, run, or block). By seeing the actual company or signer, the user is protected from running code by someone that they do not know. For example, I would trust “My University” or “Erik Costlow” but not “Unknown publisher” or someone else claiming to be me.

This feature is geared towards two types of users:

Desktop Administrators, who manage a number of users and need to control version compatibility and default dialogs to specific company applets. Desktop Administrators should learn how to control Java across these user systems. For example, “automatically run browser applets signed by our company” or “run all our browser applets with the latest secure version, except for this one internal system that we know needs Java 1.6.”

Developers, who create Java applets and Web Start applications should be aware of the role that deployment rule sets play on their end-user’s desktop.

How to create a deployment rule set

By creating a deployment rule set, desktop administrators can control execution and dialog prompts for desktop users and allow them to run known Java applets, either created by the company or used in critical systems.

Creating a deployment rule set involves a set of steps done once that can then scale out to any number of users and continue working in their future Java updates:

  1. Identify critical applets and web start applications, either by location (e.g. http://payroll.example.com), name (e.g. Solitaire), or code-sign hash.
  2. Create a file called ruleset.xml
  3. Package your ruleset.xml into a signed DeploymentRuleSet.jar
  4. Deploy your DeploymentRuleSet.jar to user desktops
  5. Verify usage of your rule set on a client desktop

Identify critical Applets and Web Start applications

Find locations of known applets that your users interact with as part of their normal work. There are many means for gathering this information, from asking/monitoring users to speaking with your director of engineering if their team is creating applets. Ultimately, they can be listed through three means:

  1. Location
    • This is a pattern matcher for URLs. You can identify applets through a simple combination of wildcards and automatic directories.
    • The benefit of location is that it is easy to collect the right information.
    • Examples:
      • https://payroll.example.com
      • *.example.com/panel
        This will implicitly cover anything located beneath the panel folder
  2. Certificate Hash
    • If you are following the security practice of signing your code so that users know your applets, you can provide a SHA-256 hash of your public certificate.
    • The benefit of a certificate hash is that it recognizes a publisher, irrespective of location. The downside is that you must find the appropriate certificate.
    • Examples of SHA-256 hashes look like 63 characters of hexadecimal: 794F53C746E2AA77D84B843BE942CAB4309F258FD946D62A6C4CCEAB8E1DB2C6
    • To get these hashes, download a signed jar file or obtain one from the developers and run:
      1. keytool -printcert -jarfile MyProgram.jar > cert.txt
      2. Open cert.txt and find the earliest relevant signature. For example, I chose ours:
        Owner: CN="Oracle America, Inc.", OU=Software Engineering, OU=Digital ID Class 3 - Java Object Signing, O="Oracle America, Inc.", L=Redwood Shores, ST=California, C=US
        and then copied the hash line appearing a little later:
        SHA256: 79:4F:53:C7:46:E2:AA:77:D8:4B:84:3B:E9:42:CA:B4:30:9F:25:8F:D9:46:D6:2A:6C:4C:CE:AB:8E:1D:B2:C6
      3. Remove the : separator characters.
  3. Title
    • Look at the JNLP launcher to identify the title of the application.
    • Title must occur only with another attribute, like location or certificate. Title may not be used alone since it exists outside signed jars and deployed locations.

For the time being, just create a list of these.

Create a file called ruleset.xml

Once you have a list of critical applets, the next step is to create a single file called rulset.xml that will look like this:

<!-- Example Deployment Rule Set that allow a desktop administrator to control end-user's execution of browser applets.
  See http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/deployment_rules.html -->
<ruleset version="1.0+">
	<rule>
		<id location="http://payroll.example.org" />
		<action permission="run" />
	</rule>
	<rule>
		<id location="http://knownvendor.example.com/program" />
		<action permission="run" version="SECURE-1.6" /><!-- For example if an application is known not to work on Java 1.7 -->
	</rule>
	<rule>
		<id location="http://localhost" />
		<action permission="run" />
	</rule>
	<rule>
		<id>
			<certificate algorithm="SHA-256"
				hash="794F53C746E2AA77D84B843BE942CAB4309F258FD946D62A6C4CCEAB8E1DB2C6" /><!-- Oracle's public certificate hash. Having this will allow things like the Java.com secure version check applet. -->
		</id>
		<action permission="run" />
	</rule>
	<rule>
		<id location="http://*.example.com">
			<certificate algorithm="SHA-256"
				hash="..." />
		</id>
		<action permission="default" version="SECURE" />
	</rule>
	<rule>
		<id /><!-- Because this is both blank and shown last, it will be the default policy. -->
		<action permission="block">
			<message>Blocked by corporate. Contact myemail@mycompany.com if you need to run this app.</message>
			<message locale="fr">Bloqué par l'entreprise. Contacter myemail@mycompany.com si vous avez besoin d'exécuter cette application.</message>
		</action>
	</rule>
</ruleset>

Complete details for creating this file can be found in the Deployment Rule Set documentation, but the gist is to specify the default action of which should run (with no interaction from the user), which should perform the default behavior (prompting the user), and which should be automatically blocked (explaining why).

Package your ruleset.xml into DeploymentRuleSet.jar

Packaging your ruleset allows the desktop administrator to apply cryptographic signatures and prevent users from overriding your policy. This requires usage of a trusted signing certificate. The easiest route to get a signature is to buy one from a certificate authority like Symantec/Verisign, Comodo, GoDaddy, or any other; but in this case I have instructed my JVM to use a custom costlow-ca certificate authority (which only works on my machine). The default certificate authority list contains about 80 authorities from which you may purchase a signing certificate.

C:\Users\ecostlow\DeploymentRuleSet>jar -cvf DeploymentRuleSet.jar ruleset.xml
added manifest
adding: ruleset.xml(in = 1492) (out= 612)(deflated 58%)

C:\Users\ecostlow\DeploymentRuleSet>jarsigner -verbose -keystore "c:\Users\ecostlow \javakeystore_keepsecret.jks" -signedjar DeploymentRuleSet.jar DeploymentRuleSet.jar costlow-ca
Enter Passphrase for keystore:
 updating: META-INF/MANIFEST.MF
   adding: META-INF/COSTLOW-CA.SF
   adding: META-INF/COSTLOW-CA.RSA
  signing: ruleset.xml

Deploy your DeploymentRuleSet.jar to user desktops

After creating the signed jar, desktop administrators should copy the DeploymentRuleSet.jar to the documented area for their platform so that rules are enforced for all users, across Java updates.

Verify usage of your rule set on a client desktop

For end-users, simply have them visit a website like http://java.com/en/download/installed.jsp and verify their Java version (this site uses an applet, so see if it runs).

For desktop administrators, test your Deployment Rule Set by opening the Java Control Panel and navigating to the Security tab:


Clicking the “View the active Deployment Rule Set” should show you your same ruleset.xml file.

End Result

After performing the steps above, desktop administrators can now better control usage of the Java dialogs and prompts for managed users that will function across Java updates. To make changes in the future, simply roll out a new distribution of the DeploymentRuleSet.jar.

Notes and what Deployment Rule Set is not:

The Deployment Rule Set features is intended for mostly enterprise users to manage their own configurations. It is not meant as a way to simply "whitelist everything just so warning dialogs go away," "force everyone to never update," or "external users please download this file onto your system to use this application." By default, specifying the version="SECURE" attribute is best unless you know specific reasons indicating compatibility with a specific JRE version.

Publicly distributed Deployment Rule Sets found to contain insecure "whitelist everything" configurations may have their signing certificate blacklisted from future use of Deployment Rule Sets.

Comments:

I've tried to follow the instructions by identifying the applet based on location. I created a self-signed certificate and imported it in java cacerts. In Internet Explorer 10 (on windows 7) the applet won't show, and the console is never visible even if it is set in the java console to be shown. I also tried accessing http://java.com/en/download/installed.jsp but only an "x" is shown in a frame and there are no error messages anywhere. The java icon is not visible in the system tray either even if it is set to be there.
Any idea how to get the java console to show up in IE 10?

Posted by guest on September 03, 2013 at 12:01 AM PDT #

One item that I ran into when testing on my system was that I had both a development (jdk1.7.0_40/jre) and runtime (jre7) on my system. Originally when running my commands, I had imported my certificate only into the development version (jdk1.7.0_40), whereas my browser was using the other (jre7).
On Windows, check your c:\Program Files\Java area and make sure you've modified the right cacerts file. You can either use keytool or just copy between areas.

Second, be sure to check your Java settings in the system control panel for two things: first to make sure that Java is enabled in the browser, and second that your "View active deployment rule set" shows your settings.

Posted by costlow on September 03, 2013 at 09:34 AM PDT #

Thank you for help!

I imported the self-signed certificate into both cacerts just to be sure.

I recalled that there was a grey window showing up in IE 10 the first time, when I run http://java.com/en/download/installed.jsp. If I click on "More Info" it tells me it wants to open up firefox to install java. I had clicked "Do not show this again".
It took me awhile to figure out how to get the grey window back("The page you are viewing uses java...") and finally found this site: https://www.greyhathacker.net/?p=610 . All I did was delete the following entry in the registry: [HKEY_CURRENT_USER\Software\Microsoft\Active Setup\Declined Install On Demand IEv5]
"{08B0e5c0-4FCB-11CF-AAA5-00401C608501}"=""
I then got the grey window back, but I don't get why IE 10 wants me to install java 7u25 when I got 7u40 for testing the deploymentruleset.
I got the applet to run in firefox(actually waterfox), but I can't rely on that because the enterprise web application that will use the applet is only for IE 10. For some reason java 7u40 does not run in IE 10, so I can't test if the deploymentruleset is a good solution.
Previously I got the applet to run just fine, but was it java 7u21 or 25 that broke it so that it can't use self-signed certificates. The customer runs our enterprise web application on their own servers and trust our code, so I don't see how it could me more secure by paying a few 100 $ per year just to show a certificate. I'm still positive the deploymentruleset will come in and save the day in time before the final launch.

Posted by guest on September 03, 2013 at 10:37 PM PDT #

Thanks for the instructions, especially the part about finding the SHA-256 certificate hash. That part was a bit of a head-scratcher when just following the information in the Deployment Rule Set documentation.

Now a question: Is the use of a ruleset file the intended method for Java applet developers to test their own jar files internally by signing with a self-signed cert, before they release the jar in production with a CA-issued cert?

For example, in our organization, developers do not have access to the "official" CA cert used to sign our production jar, so our build system uses a self-signed cert instead.

Prior to Java 7u40, the self-signed cert could be remembered as a trusted cert in the Java keystore, but this feature has been removed and the self-signed cert prompt appears every time, which gets old very fast.

Is the deployment rule set the way to avoid the prompt every time, or are there other options for developers of RIAs that can be used to avoid packaging and signing jars for testing?

Thanks

Posted by jons on September 04, 2013 at 11:24 AM PDT #

Hi jons, the Deployment Rule Set is aimed more at the enterprise desktop administrator who needs to manage Java installations and default actions across a large number of users.
As an individual applet developer, you probably have full control over your machine to add your own certificate wherever you need. In the above examples, I just turned myself into a certificate authority that's only trusted on my own machine.
In either case, when you go to establish what certificates are trusted, it helps to have the list of which keystores are where
(http://docs.oracle.com/javase/7/docs/technotes/guides/deployment/deployment-guide/properties.html#properties)

Posted by costlow on September 04, 2013 at 03:07 PM PDT #

I'm currently having a problem forcing a webstart app to run properly. The app uses Java 6 Update 23. Here's my ruleset as an example:

<ruleset version="1.0+">
<rule>
<id location="https://someserver.com/webstartapp" />
<action permission="run" version="1.6.0_23" />
</rule>
</ruleset>

Now that I have Java 7 Update 40 installed, it still isn't running properly. I already checked the "View the active Deployment Rule Set" area and it loaded my ruleset properly. I then tweaked a little bit by changing it to version 1.6.0_24 to see if it blocks it, but it didn't. Currently use High mode. Is it a bug or am I doing something wrong?

Posted by guest on September 16, 2013 at 07:29 AM PDT #

Your ruleset looks correct to me -- from the Deployment Rule Set documentation, the version attribute indicates "If the version attribute is not present, the RIA is run with the latest JRE available."
When you have 6u23 installed, apps from that location will run on 6u23. But if you specify 6u24 and don't have it, your system will use the most recent version available.

Also note that clients don't auto-download specific JRE versions specified by the application, to prevent malicious apps from saying that they require versions below the secure baseline.

Posted by costlow on September 16, 2013 at 10:18 AM PDT #

The tutorial is great, up to the point of verifying the ruleset took. Everything else up to that point seems to be OK/no errors. I go to the control panel applet, but no ruleset. Everything else seems to work. Using Windows. Any suggestions of where to start troubleshooting?

Posted by guest on September 16, 2013 at 10:48 AM PDT #

I have created a deployed a ruleset. However I am running into issues.

Here is my ruleset.

<!-- Example Deployment Rule Set that allow a desktop administrator to control end-user's execution of browser applets.
See http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/deployment_rules.html -->
<ruleset version="1.0+">
<rule>
<id title="Meditech Viewer" id location="http://192.168.0.35/applets" />
<action permission="run" version="1.5.0_8" />
</rule>
<rule>
<id title="Amicas Pacs Website" id location="http://pacsprod.hmh.local/applets/phoenix" />
<action permission="run" version="1.6.0_29" />
</rule>
<rule>
<id title="Kronos" id location="http://adkronos2k8.hmh.local" />
<action permission="run" version="1.6.0_29" />
</rule>

<rule>
<id /><!-- Because this is both blank and shown last, it will be the default policy. -->
<action permission="block">
<message>Blocked by corporate. Contact myemail@mycompany.com if you need to run this app.</message>
</message>
</action>
</rule>
</ruleset>

When I try to launch my amicas pacs website I get an applicaiton blocked error. Name viewerInstaller location http://pacsprod.hmh.local/applets/phoenix/

the locaion id in my second rule is the exact same address. What am I doing wrong?

Posted by guest on September 16, 2013 at 01:45 PM PDT #

To troubleshoot verifying your Deployment Rule Set, be mindful with self-signed certificates. If you are a developer using a JDK, try the full path to your commands to verify with the non-JDK JRE. It's likely that you're verifying against jdk1.7.0_40/jre instead of the jre7 that your system is using. See Java Control Panel->Java->View Button as well.

With regards to the above rule set example, make sure you're using the title from the JNLP, not the title of the web page. It looks like that name is actually "viewInstaller."

Posted by costlow on September 17, 2013 at 09:21 AM PDT #

Thanks for your response. As far as the title is concerned I did try it with the exact name in the title box and it did not work. I also read that if the title command was left out that it would not worry about the title and go on. Here is the more detail logs I gathered.

com.sun.deploy.security.BlockedException: Can not verify rule set jar
at com.sun.deploy.security.SandboxSecurity.showBlockedDialog(Unknown Source)
at com.sun.deploy.security.TrustDecider.isAllPermissionGranted(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.isTrustedByTrustDecider(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.getTrustedCodeSources(Unknown Source)
at com.sun.deploy.security.CPCallbackHandler$ParentCallback.strategy(Unknown Source)
at com.sun.deploy.security.CPCallbackHandler$ParentCallback.openClassPathElement(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.getJarFile(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.access$1000(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.ensureOpen(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$JarLoader.<init>(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: com.sun.deploy.security.BlockedException: Can not verify rule set jar
at com.sun.deploy.security.ruleset.DeploymentRuleSet.verifyRuleSetFile(Unknown Source)
at com.sun.deploy.security.ruleset.DeploymentRuleSet$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.deploy.security.ruleset.DeploymentRuleSet.initialize(Unknown Source)
... 2 more

Does anything there stand out to you? I am not a Java Developer and the machine I am testing with does not have JDK on it.

Is there a quick way to see what version of java the RIA is requesting? I read here (http://docs.oracle.com/javase/tutorial/deployment/jar/build.html )
It says that the requested version must match the version in the action variable.

Posted by guest on September 17, 2013 at 12:20 PM PDT #

I think the whole problem might be that I have not signed the deploymentruleset.jar This is a completely new process to me. I was able to download my domain cert and use keytool -import to import this to my keystore. I can find .keystore in c:\users\myusername\ however I cannot get the jarsigner -verbose -keystore "c:\Users\myusername \.keystore.jks" -signedjar DeploymentRuleSet.jar DeploymentRuleSet.jar costlow-ca to work. It tells me that the specified file cannot be found. Do you have any advice on this?

Posted by guest on September 18, 2013 at 08:47 AM PDT #

Right, if the DeploymentRuleSet.jar is not signed then it won't be applied.
In the example above, "costlow-ca" was the alias for the certificate that I created. All code-signing Certificate Authorities that I looked at showed instructions for generating these keys. The point here is that keys are each identified by an alias.
There is a tutorial for generating keys at http://docs.oracle.com/javase/tutorial/security/toolsign/step3.html (their alias is "signFiles") or you can look at instructions from your code-signing authority, which is probably easiest. I listed a few under "Purchase a signing certificate" at https://blogs.oracle.com/java-platform-group/entry/code_signing_understanding_who_and

Posted by costlow on September 18, 2013 at 09:10 AM PDT #

Hi , Can you explain how I can create a deploymentset for EBusiness Suite? EBS login url is http://server:port/OA_JAVA/oracle/apps/fnd/jar/fndforms.jar

Posted by sudhir on September 18, 2013 at 08:45 PM PDT #

Sudhir, you can whitelist that by using something like <rule><id location="server:port/OA_JAVA" /><action permission="run" version="SECURE" /></rule>
Basically, go as specific in the URL path as you can to include any RIAs that need to run.
See the example above and its linked documentation for complete details.

Posted by costlow on September 19, 2013 at 10:53 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

Science Duke
This blog contains topics related to Java SE, Java Security and Usability. The target audience is developers, sysadmins and architects that build, deploy and manage Java applications. Contributions come from the Java SE Product Management team.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today