Wednesday Jul 02, 2014

Diagnosing TLS, SSL, and HTTPS

When building inter-connected applications, developers frequently interact with TLS-enabled protocols like HTTPS. With recent emphasis on encrypted communications, I will cover the way in which the JDK evolves regarding protocols, algorithms, and changes, as well as some advanced diagnostics to better understand TLS connections like HTTPS.

Most developers will not have to do this level of diagnosis in the process of writing or running applications. In the event that you do, the following information should provide enough information to understand what's happening within secure connections.

Stability: The evolution of protocols and algorithms

For the last 15 years (since 1998), the Java platform has evolved through the Java Community Process where companies, organizations, and dedicated individuals develop and vote on specifications to determine what makes up the Java Platform. Much of the efforts are centered on compatibility, like the TCK, ensuring that different implementations are compatible with each-other and that developers can predict how their applications will run. We are not changing critical default options (like TLS protocol) within minor versions.

The following chart depicts the protocols and algorithms supported in each JDK version:


JDK 8
(March 2014 to present)
JDK 7
(July 2011 to present)
JDK 6
(2006 to end of public updates 2013)
TLS Protocols
TLSv1.2 (default)
TLSv1.1
TLSv1
SSLv3
TLSv1.2
TLSv1.2
TLSv1 (default)
SSLv3


TLSv1 (default)
SSLv3
JSSE Ciphers:
Ciphers in JDK 8
Ciphers in JDK 7
Ciphers in JDK 6
Reference:
JDK 8 JSSE JDK 7 JSSE JDK 6 JSSE
Java Cryptography Extension, Unlimited Strength (explained later)
JCE for JDK 8 JCE for JDK 7 JCE for JDK 6

Sample Java code for making an HTTPS connection

Making an HTTPS connection in Java is relatively straight-forward. I will post the code here with the intent focused on tuning and understanding the underlying capabilities.

Sample back-end code for making an SSL connection:

final URL url = new URL("https://example.com");
try(final InputStream in = url.openStream()){
  //…
}

Or the connection can be tuned through a cast:

final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
//operate on conn
conn.connect();
try(final InputStream in = conn.getInputStream()){
  //…
}

Example: Qualys SSL Labs' "View My Client" Page

Qualys SSL Labs maintains a collection of tools that are helpful in understanding SSL/TLS connections. One in particular is a View My Client page, which will display information about the client connection. By integrating with that page, I was able to control the implementation as I used different Java tuning parameters.

To test parameter tuning, I implemented a small JavaFX application in JavaScript. It displays that page in a WebView, showing information about the underlying Java SSL/TLS client connection. You can find the code in the appendix.

JSSE Tuning Parameters

When diagnosing TLS-related issues, there are a number of helpful system properties. They are generally covered in their relevant sections of JSSE but this single collection may help anyone looking to understand the flexibility of Java’s implementation or diagnose connection details.

javax.net.debug
 Prints debugging details for connections made.
Example: -Djavax.net.debug=all or -Djavax.net.debug=ssl:handshake:verbose
https.protocols
Controls the protocol version used by Java clients. For older versions, this can update the default in case your Java 7 client wants to use TLS 1.2 as its default.
Example: -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
http.agent
When initiating connections, Java will apply this as its user-agent string. Modifying this will handle cases where the receiving party responds differently based on the user-agent.
Example: -Dhttp.agent="known agent"
java.net.useSystemProxies
java.net.useSystemProxiesUse proxy details from the operating system itself.
Example: -Djava.net.useSystemProxies=true
http.proxyHost
http.proxyPort
The proxy connection to use for HTTP connections.
Example: -Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080
https.proxyHost
https.proxyPort
The same as above, except that configuration is separate between HTTP and HTTPS.
http.proxyUser
http.proxyPassword
https.proxyUser
https.proxyPassword
Password-based credentials for the above proxies.

Many other protocols and properties can be found within the following areas:

Example of diagnosing a problem

When making an HTTPS connection, let’s assume that the client threw the following exception due to a failed handshake with the server:

 javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

SSLHandshakeException is a subclass of the IOException, so you do not need to catch is explicitly. Most developers will not need an explicit catch, but it may help you more easily diagnose the cause of any IOException.

When applying the -Djavax.net.debug=all property from above, the failure associated with this SSLHandshakeException would appear immediately after algorithm negotiation in the logs.

 JDK 7 (fails on unsupported algorithm) JDK 8 (works fine)
Cipher Suites: […Long list of ciphers…]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {…}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: HOST]
***
main, WRITE: TLSv1 Handshake, length = 168
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT:  fatal, handshake_failure
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Cipher Suites: […Long list of ciphers…]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {…}
Extension ec_point_formats, formats: [uncompressed]
Extension signature_algorithms, signature_algorithms: …
Extension server_name, server_name: [type=host_name (0), value=HOST]
***
main, WRITE: TLSv1.2 Handshake, length = 226
main, READ: TLSv1.2 Handshake, length = 89
*** ServerHello, TLSv1.2
RandomCookie:  GMT: -1809079139 bytes = { …}
Session ID:  {…}
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
Extension ec_point_formats, formats: [uncompressed, ansiX962_compressed_prime, ansiX962_compressed_char2]
***
%% Initialized:  [Session-1, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256]
** TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
main, READ: TLSv1.2 Handshake, length = 2308

In the case above, the failure occurred during the handshake. The most likely cause for that is algorithm support. The JDK provides a separate package called JCE Unlimited Strength, designed to add stronger algorithm support than what’s available by default. Qualys SSL Labs provides a different server SSL test that will enumerate which algorithms a server supports.

Many TLS error messages are covered in a few pieces of documentation:

Adding stronger algorithms: JCE Unlimited Strength

In a high security environment, one way of strengthening algorithms in the JDK is through the JCE Unlimited Strength policy files. In this particular case, replacing those policy files within JDK 7 allows it to use the stronger variants of existing algorithms and connect successfully.

JCE Unlimited Strength downloads: JDK 8, JDK 7, or JDK 6.

Appendix

The following code will open Qualys SSL Labs’ View My Client page within a Java client. To test configurations, run this like:

jjs -fx viewmyclient.js
jjs -fx -Dhttps.protocols=TLSv1 viewmyclient.js

var Scene = javafx.scene.Scene;
var WebView = javafx.scene.web.WebView;
var browser = new WebView();
browser.getEngine().load("https://ssllabs.com/ssltest/viewMyClient.html");
$STAGE.scene = new Scene(browser);
$STAGE.show();

Wednesday Jun 11, 2014

Nashorn, the rhino in the room

Nashorn is a new runtime within JDK 8 that allows developers to run code written in JavaScript and call back and forth with Java. One advantage to the Nashorn scripting engine is that is allows for quick prototyping of functionality or basic shell scripts that use Java libraries. The previous JavaScript runtime, named Rhino, was introduced in JDK 6 (released 2006, end of public updates Feb 2013). Keeping tradition amongst the global developer community, "Nashorn" is the German word for rhino.

The Java platform and runtime is an intentional home to many languages beyond the Java language itself. OpenJDK’s Da Vinci Machine helps coordinate work amongst language developers and tool designers and has helped different languages by introducing the Invoke Dynamic instruction in Java 7 (2011), which resulted in two major benefits: speeding up execution of dynamic code, and providing the groundwork for Java 8’s lambda executions. Many of these improvements are discussed at the JVM Language Summit, where language and tool designers get together to discuss experiences and issues related to building these complex components.

There are a number of benefits to running JavaScript applications on JDK 8’s Nashorn technology beyond writing scripts quickly:

  1. Interoperability with Java and JavaScript libraries.
  2. Scripts do not need to be compiled.
  3. Fast execution and multi-threading of JavaScript running in Java’s JRE.
  4. The ability to remotely debug applications using an IDE like NetBeans, Eclipse, or IntelliJ (instructions on the Nashorn blog).
  5. Automatic integration with Java monitoring tools, such as performance, health, and SIEM.

In the remainder of this blog post, I will explain how to use Nashorn and the benefit from those features.

Nashorn execution environment

The Nashorn scripting engine is included in all versions of Java SE 8, both the JDK and the JRE. Unlike Java code, scripts written in nashorn are interpreted and do not need to be compiled before execution.

Developers and users can access it in two ways:

  • Users running JavaScript applications can call the binary directly:
    jre8/bin/jjs
    • This mechanism can also be used in shell scripts by specifying a shebang like #!/usr/bin/jjs
  • Developers can use the API and obtain a ScriptEngine through:
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    • When using a ScriptEngine, please understand that they execute code. Avoid running untrusted scripts or passing in untrusted/unvalidated inputs. During compilation, consider isolating access to the ScriptEngine and using Type Annotations to only allow @Untainted String arguments.

One noteworthy difference between JavaScript executed in or outside of a web browser is that certain objects will not be available. For example when run outside a browser, there is no access to a document object or DOM tree. Other than that, all syntax, semantics, and capabilities are present.

Examples of Java and JavaScript

The Nashorn script engine allows developers of all experience levels the ability to write and run code that takes advantage of both languages. The specific dialect is ECMAScript 5.1 as identified by the User Guide and its standards definition through ECMA international.

In addition to the example below, Benjamin Winterberg has a very well written Java 8 Nashorn Tutorial that provides a large number of code samples in both languages.

Basic Operations

A basic Hello World application written to run on Nashorn would look like this:

#!/usr/bin/jjs
print("Hello World");

The first line is a standard script indication, so that Linux or Unix systems can run the script through Nashorn. On Windows where scripts are not as common, you would run the script like: jjs helloWorld.js.

Receiving Arguments

In order to receive program arguments your jjs invocation needs to use the -scripting flag and a double-dash to separate which arguments are for jjs and which are for the script itself:
jjs -scripting print.js -- "This will print"

#!/usr/bin/jjs
var whatYouSaid = $ARG.length==0 ? "You did not say anything" : $ARG[0]
print(whatYouSaid); 

Interoperability with Java libraries (including 3rd party dependencies)

Another goal of Nashorn was to allow for quick scriptable prototypes, allowing access into Java types and any libraries. Resources operate in the context of the script (either in-line with the script or as separate threads) so if you open network sockets and your script terminates, those sockets will be released and available for your next run.

Your code can access Java types the same as regular Java classes. The “import statements” are written somewhat differently to accommodate for language. There is a choice of two styles:

  1. For standard classes, just name the class: var ServerSocket = java.net.ServerSocket
  2. For arrays or other items, use Java.type: var ByteArray = Java.type("byte[]")
    You could technically do this for all.

The same technique will allow your script to use Java types from any library or 3rd party component and quickly prototype items.

Building a user interface

One major difference between JavaScript inside and outside of a web browser is the availability of a DOM object for rendering views. When run outside of the browser, JavaScript has full control to construct the entire user interface with pre-fabricated UI controls, charts, or components. The example below is a variation from the Nashorn and JavaFX guide to show how items work together.

Nashorn has a -fx flag to make the user interface components available. With the example script below, just specify: jjs -fx -scripting fx.js -- "My title"

#!/usr/bin/jjs -fx
var Button = javafx.scene.control.Button;
var StackPane = javafx.scene.layout.StackPane;
var Scene = javafx.scene.Scene;
var clickCounter=0;
$STAGE.title = $ARG.length>0 ? $ARG[0] : "You didn't provide a title";
var button = new Button();
button.text = "Say 'Hello World'";
button.onAction = myFunctionForButtonClicking;
var root = new StackPane();
root.children.add(button);
$STAGE.scene = new Scene(root, 300, 250);
$STAGE.show();
function myFunctionForButtonClicking(){
  var text = "Click Counter: " + clickCounter;
  button.setText(text);
  clickCounter++;
  print(text);
}

For a more advanced post on using Nashorn to build a high-performing UI, see JavaFX with Nashorn Canvas example.

Interoperable with frameworks like Node, Backbone, or Facebook React

The major benefit of any language is the interoperability gained by people and systems that can read, write, and use it for interactions. Because Nashorn is built for the ECMAScript specification, developers familiar with JavaScript frameworks can write their code and then have system administrators deploy and monitor the applications the same as any other Java application.

A number of projects are also running Node applications on Nashorn through Project Avatar and the supported modules.

In addition to the previously mentioned Nashorn tutorial, Benjamin has also written a post about Using Backbone.js with Nashorn.

To show the multi-language power of the Java Runtime, there is another interesting example that unites Facebook React and Clojure on JDK 8’s Nashorn.

Summary

Nashorn provides a simple and fast way of executing JavaScript applications and bridging between the best of each language. By making the full range of Java libraries to JavaScript applications, and the quick prototyping style of JavaScript to Java applications, developers are free to work as they see fit.

Software Architects and System Administrators can take advantage of one runtime and leverage any work that they have done to tune, monitor, and certify their systems.

Additional information is available within:

Tuesday May 20, 2014

Compact Profiles: Space and Security

Compact Profiles provide a way for developers and device manufacturers to package and update Java SE on space-constrained devices. Teams building software for those devices can trim the size of the embedded JRE by choosing a Compact Profile without items that are not used by their application. Additional details are present in Java Magazine’s March Issue, as well as the Java SE 8 launch videos “Developing Embedded Applications with Java SE 8 Compact Profiles.”

By shrinking the size of the JRE, we enable developers to use their existing Java skills in new areas and take advantage of hardware like the Raspberry Pi, the BeagleBoard, and many others. This post will cover a few aspects of Compact Profiles:

  • Comparisons between complete JRE and each profile
  • Threat modeling of a Compact Profile
  • Identifying and creating your compact JRE
  • Configuring, installing, and updating your compact JRE
  • Summary of compact profiles

Comparisons between the complete JRE and each profile

To see the various areas that Java runs in, here is a chart of sizes:

 Version Approx. Size Installed
Used for
JDK 8
Most developers use this.
431MB
Developers building Java applications and/or profiling them with Mission Control.
JRE 8
Most client systems use this.
163MB
Clients running Java applications on their Windows/Max/Linux desktop.
Server JRE 8
136MB
Server systems, for running back-end processes or application servers. This JRE can run servlet containers and compile JSPs. It is smaller than the regular JDK because it does not contain the browser plug-in, Java Mission Control, or VisualVM.
Java SE Embedded 8

Embedded devices like the Raspberry Pi, BeagleBoard, etc.
Java SE Embedded compact 3
21MB
Embedded devices requiring Kerberos or remote monitoring like JMX, but not APIs like Swing, CORBA, and Java Sound.
Java SE Embedded compact 2
15MB
Embedded devices making use of SQL connectivity or XML processing, but not any functionality from compact3.
Java SE Embedded compact 1
11MB
Embedded devices requiring a minimal version of Java SE, but not any functionality from compact2.
Java ME Embedded
Varies based on highly constrained device.
Highly constrained embedded devices.

If you are working on an embedded device and wondering which profile you should use, please see the video “Choosing a Compact Profile for your Deployment.” It is also possible to mix-and-match certain items in different profiles through extensions.

Complete details for each profile, including API listing, are located on the Compact Profiles page and within JEP 161.

Threat modeling of a Compact Profile

Compact profiles also contain a different threat model than the typical JDK Conceptual Diagram. Although the runtime is similar from the application’s point of view, the profiles are defined by items that are NOT present. For example any risk or potential misuse associated with Java2D would be mitigated in the compact3 profile, which does not include that component.

The Server JRE is a similar example: by not even having the deployment components of RIAs and browser plugins, the risk is eliminated (servers typically do not use that functionality).

It is possible to reduce and mitigate other threats as well given the control that the device manufacturer or operator has over installation/updates of the JRE. For example after creating a compact profile, one could decrease the threat model’s scope of Spoofing and likely Information Disclosure by updating the default keystore to remove everything except known-needed roots and then requiring encryption.

Identifying and creating a Compact Profile

JDK 8 provides a new tool called JDeps that can look at a collection of JAR and CLASS files and report on which compact profiles are used. When using JDeps to evaluate profiles, the report is transitive: if all your code fits in compact1 but you require something else that needs the larger compact2, then you must either use compact2 or remove the offending component.

Example usage of this is:
jdeps -profile filename.jar

filename.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\jce.jar (compact1)
filename.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\rt.jar (Full JRE)
filename.jar -> AnotherPackage.jar
   your.package (filename.jar)
      -> com.sun.deploy.config   JDK internal API (deploy.jar)
      -> java.io                 compact1
      -> java.lang               compact1
      -> java.lang.invoke        compact1
      -> java.math               compact1

Additional details can be found in Jim Connors’ blog, Compact Profiles Demonstrated.

JDeps can also be used to identify reliance of non-spec internal JDK APIs that are subject to removal, so that you can move to the appropriate public replacement.

Creating, configuring, and updating your Compact Profile

Once you have identified the appropriate profile, you can create a compact profile that will run on the target device.

  1. Download the version of Java SE Embedded for your target platform.
  2. Unzip the version that you downloaded into its usual ejdk folder.
  3. Use the included bin/jrecreate command to create the profile.
    This step requires a JAVA_HOME variable, which should point to your system’s java installation and not anything related to the target device.

For non-embedded OpenJDK, the profiles must be built separately on Linux.

Examples:

  • To create the bare minimum compact1 profile:
    jrecreate -d ~/compact1 -profile compact1
  • To create the bare minimum compact1 profile that also has the sun elliptical curve extension:
    jrecreate -d ~/compact1WithEC -profile compact1 -x sunec

Once created, simply copy the newly created folder to your device and run it like any other application.

Configuring your Compact Profile

Once the compact profile has been created, it contains several noteworthy items beyond the JRE itself. One file in particular, called bom, lists the bill of materials for this compact JRE. By having that file, you and any subsequent users will be able to see precisely what went into this profile, when it was created, and other useful piece of information.

You may then customize the information as you would any other JRE. All configuration files are present, such as such as network configuration and proxy information, timezone data, etc.

Updating your Compact Profile

Any compact profile that you create is outside the scope of typical package management systems like RPM. For a device manufacturer, there are many commercial systems which exist to handle this. It is recommended to have a mechanism for patching devices, should the need arise.

Although devices may perform minimal operations, it is reasonable to plan ahead for software updates of your applications, the compact Java profile, as well as any underlying operating system and its libraries.

Summary

Compact profiles provide a way to trim down the Java runtime in order to fit on embedded devices, either as a system component or part of an application. Not only can compact profiles shrink the size of a Java runtime down to 11MB, it also decreases the potential attack surface.

Thursday May 01, 2014

Deployment Rule Set by Example

Recently I encountered a situation whereby a System Administrator needed to adjust thieir systems to run a specific RIA on an older version of Java. By using Deployment Rule Sets, we were able to achieve the desired outcome. The specific RIA ran using the older version of Java with no prompts to the end users, while all other RIA applications used the latest, most secure version of Java.

This post is intended for System Administrators managing a white list within an organization.

Assessing the environment

In this particular case, the RIA itself was designed to run on Java 6 update 31 (released in February 2012, but public updates for Java SE 6 ended in February 2013). That also means that it does not adhere to the security requirements introduced in a recent Java SE 7 Critical Patch Update. Because this RIA was known to be safe and necessary for business operations, the goal was to be able to execute it with no prompts.

Installing multiple versions of Java

When delegating RIAs to use older Java versions, it is necessary to have at least two installations available:

  1. The latest Java version, which will be used by default except in cases where you configure it to delegate to the older version. We installed this as the default patch-in-place.
  2. The specific older versions needed by the RIA, which will only be accessible through your Deployment Rule Set. We installed this as a static installation to prevent any interference in case that a different Java SE 6 version had to be installed for something else.
    1. Although older versions are not updated with the latest security patches and not recommended for use in production, the Deployment Rule Set mitigates the definition of "in production" because the older JRE is only accessible from explicitly whitelisted areas.

Information about these installation types can be found within a previous post, Managing Multiple Java Versions. Comprehensive documentation is provided by Oracle about silent installation switches for package management as well as disabling third-party sponsors.

Once items were installed, we had two noteworthy locations on the Windows desktops (others may be available as well, but these are the important ones):

  1. C:\Program Files\Java\jre7
  2. C:\Program Files\Java\jre1.6.0_31

Creating the Deployment Rule Set

Instructions on creating a Deployment Rule Set are available in the post Introducing Deployment Rule Sets or in the complete Deployment Rule Set documentation.

The actual deployment rule set used looks like:

<!-- Example Deployment Rule Set that allow a desktop administrator to control end-user's execution of browser applets.
  See http://docs.oracle.com/javase/8/docs/technotes/guides/jweb/security/deployment_rules.html -->
<ruleset version="1.0+">
    <rule>
        <id location="https://java.com/" />
        <action permission="run" version="SECURE" />
    </rule>
    <rule>
        <id location="http://internal.example.com/" />
        <action permission="run" version="1.6.0_31" />
    </rule>
</ruleset>

In this example, we were able to identify and test each item. For example, the first rule checks that users could run the normal Java.com detection applet without any prompts. That demonstrated the correct setup of the DRS. Once successfully set up, the second rule allowed us to target their application.

Ensure the DeploymentRuleSet.jar is signed correctly for each Java installation

Most certificates from Certificate Authorities should work out of the box. The certificate used to sign your Deployment Rule Set must be trusted by each Java installation.

After your Deployment Rule Set is in place (in the documented area), the easiest way to check is to look at the control panel. Instructions for checking this are in the previous post, Introducing Deployment Rule Sets, under the “Verify usage of your rule set on a client desktop.”

Importing certificates into the older Java version

Although most administrators do not need this step, sometimes the older JRE does not contain the newer root certificate. In that case, it is necessary to locate the CA’s root certificate and explicitly import it:

"C:\Program Files\Java\jre1.6.0_31\bin\keytool" -importcert -keystore "C:\Program Files\Java\jre1.6.0_31\lib\security\cacerts" -alias AuthNameNoSpaces -file TheRootTheyProvided.cer

Once we had the root’s certificate inside both keystores, the RIA launched correctly on the older Java 6.

Verifying "is this working right"

Testing your Rule Set involves opening the RIA and verifying execution. Other system tools will help check and verify any assumptions. In addition to launching RIAs like the Java.com detection applet, the regular Task Manager will help understand which versions are getting launched.

Within the basic Task Manager, the Processes tab can show a command line column. In the case that you are launching a different version, you can show the Command Line column. In this screenshot, I’ve shrunk the view but it’s easy to see what I am running.

Screenshot of command-line in Win7 task manager

There are other tools available to view a process chain as well, where you will see a chain that looks like:

  • iexplorer.exe
    • jp2launcher.exe
      • java.exe (from the default JRE installation area)
        • java.exe (from your targeted JRE usage area)

Automating Package Installation

Once the item was identified as working, we were able to integrate the previous silent installation switches to roll the installations out onto different computers.

Most users or members of staff can run basic installers or scripts as needed. Large enterprises with desktop management systems often combine silent installation switches and customization commands (like the keytool import) with MSI creators, and then roll a single file out for installation.

I will refrain from discussing package creation and roll-out in detail. Use the right mechanism that works within your organization.

Reminder about external distribution

The Deployment Rule Set feature is intended for organizations 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 restricting compatibility to 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.

Additional Helpful Information

Appendix: Debugging if things to not work as expected

System Administrators new to Java may find the Java console useful to understand what is happening. Most users neither turn on nor see this console.

By turning the console on in the Java control panel, we were able to see execution.

Screenshot of java console

The first line in that file indicates the current version in use: JRE 1.8.0-b132. This is clearly not 1.6.0_31, meaning that it matches the first rule.

When we began using the Deployment Rule Set that delegated to Java 6 update 31, two major things happened:

  1. In the Task Manager process tree, two Java processes appeared. The first was the latest Java, the second was the older version connected to this process.
  2. Because we had the Java console turned on, two consoles appeared: one for each version.

If you press ‘5’ on that console, it will output a significant amount of log information. I won’t paste a sample log here because they can get long, but the really interesting parts look like:

 Sample from log
What it tells us
 Using JRE version 1.8.0-b132 Java HotSpot(TM) 64-Bit Server VM  At the top, this tells us which version is currently in use.
 Lines beginning with “ruleset:”
ruleset: RuleSetParser.parse() returning 2 rules:
 These tell what is happening with the DRS, isolated from other information.
 Lines that talk about “ruleset” and “location”
ruleset: finding Deployment Rule Set for
        title: Java Uninstall Applet
        location: https://java.com/applet/JavaRemovalTool/launch.jnlp
        jar location: https://java.com/applet/JavaRemovalTool/JavaRemovalTool.jar
        jar version: null
        isArtifact: true

 The location information helps me understand if I told the ruleset to whitelist the right place.
Sometimes, though not often, the browser URL and actual application URL are different.
In the example to the left, both are on https://java.com
Although my browser visits an area, /en/download/installed.jsp the actual files are hosted in /applet.
That means copying from my browser’s address bar would not have worked.

Appendix: Identifying applications by Certificate Hash or Location

The two primary ways of creating a deployment rule are by location or certificate hash.

  • Certificate hashes help identify a publisher. For example I could automatically run Oracle RIAs by creating a rule to run RIAs whose certificate hash is 794F53C746E2AA77D84B843BE942CAB4309F258FD946D62A6C4CCEAB8E1DB2C6.
    This rule would take effect regardless of where the RIA was hosted.
  • Location identifies where the RIA (specifically its JAR files) is hosted. This is sometimes easier to copy from a browser’s address bar and can be used in cases where the RIA publisher did not actually sign the RIA.

If the RIA uses LiveConnect (javascript integration), you must create a Location rule to whitelist the hosting domain and accept the LiveConnect calls.

Within the Java Console, there are also ways to locate both of those identifiers.

  • security: SHA-256Certificate finger print: Long certificate hash
  • basic: Plugin2ClassLoader.addURL parent called for http://url.example.com/path/someFile.jar

Those will help identify the items that the RIA plugin is seeing, so then you can look for one of the following messages:

  1. ruleset: Rule hash matches certificate hash (or a similar message about location)
  2. ruleset: no rule applies, returning Default Rule

Thursday Apr 17, 2014

Secure Coding Guidelines for Java SE

With so much happening around the Java platform, it’s understandable if you missed the recent improvements we made to the Secure Coding Guidelines for Java SE.  In January 2014 the Java Platform Group released a significant update, Java 7 Update 51 establishing code-signing as the default for Applets and Web Start applications.  Following in March 2014, we hit another major milestone with the long anticipated release of Java SE 8.

There are a number of improvements to the Secure Coding Guidelines for Java SE.  On the surface, the larger domains of the coding guidelines like Fundamentals and Denial of Service are the same but content has been improved throughout each domain based upon changes to Java’s threat landscape.  Likewise, small but noteworthy improvements to content navigation were made to the domains in table of contents facilitating quick navigation for readers.

Beyond content improvements, code examples were refreshed to highlight new Java 8 features like Lambda.  While our coding guidelines are updated for Java SE 8, most guidance is relevant to older versions like Java SE 7.  Please keep in mind secure application coding and design is only one component in a secure solution.  Building secure solutions requires OS security hardening, application and infrastructure hardening, patching all components on a timely schedule, etc.  More information about Java security is available in the Security Resource Center for Java.

Monday Apr 07, 2014

JavaOne 2014 Security Track Early Acceptance Sessions

J1 LogoJavaOne 2014 is Oracle's flagship software developers conference event for Java.  Security has been a focus at the conference for many years but last year Oracle brought security to the forefront by including it as a track.  If you have ideals for interesting Java security sessions we would be delighted to review them.  The JavaOne CFP is open until April 14, 2014.

 Back to the security track, each year the tracks highlight their early acceptance sessions to build momentum for the conference.  This year I would like to highlight the following early acceptance sessions for the security track and show a little of what we are planning.  

CON2120 Anatomy of Another Java Zero-Day Exploit

Presenter:  David Svoboda, Software Security Engineer, Carnegie Mellon

Abstract:  Java was recently hit by several major exploits. These exploits were written in pure Java and relied on several obscure components of the Java library. Understanding how exploits undermine Java security is a fundamental step in understanding and improving Java security and producing secure Java code. Consequently, this session demonstrates and examines a public exploit. It dissects the code of the exploit and illustrates how the exploit managed to attack an unpatched Java Virtual Machine, focusing on the techniques the exploit used, with references to relevant guidelines from the CERT Oracle Secure Coding Standard for Java. The session concludes with an explanation of how Java was patched to defeat the exploit.

CON1713 Leveraging Open Source for Secure Java Website Construction

Presenter:  Jim Manico, Secure Coding Instructor, Manicode Security (JavaOne Rock Star)

Abstract:  The need to master the skills required to build secure Java web and webservice applications gets stronger every day. There is help for you in the world of opens source! Do not build your own web application security controls from scratch! This presentation describes the use of several Oracle, OWASP, Apache and Google open source Java projects that are essential tools for constructing a secure web application.

In addition to community speakers, we will have Oracle experts from the Java security team to discuss new security features and improvements like the recent release of Java SE 8.  See you at JavaOne!

Tuesday Apr 01, 2014

Java 8's new Type Annotations

Java 8 introduces two important changes to Annotations designed to help developers produce better code and improve the accuracy of automated code analysis to verify that quality.

Quick Annotations Webinar

There is a great video explaining the new improvements in the Java 8 Launch Webinars called “Enhanced Metadata - Annotations and Access to Parameter Names” by Alex Buckley and Michael Ernst.

Annotation Improvements

Type Annotations allow developers to write annotations in more places than before. The compiler can then verify these annotations, for example identifying uses of null values, accidental value modifications, and cases where data crosses a trust boundary without proper validation. By moving some annotatable information from the Javadoc (understood only by people) and into the code (understood by both people and analyzers), it is easier to understand intent and verify the absence of certain errors.

Repeating Annotations make it easier for authors of these annotations because there is less need for wrapper annotations.

The Checker Framework provides a few Type Annotations that could benefit both library and application developers, such as:

  • @NonNull – The compiler can determine cases where a code path might receive a null value, without ever having to debug a NullPointerException.
  • @ReadOnly – The compiler will flag any attempt to change the object.  This is similar to Collections.unmodifiableList, but more general and verified at compile time.
  • @Regex – Provides compile-time verification that a String intended to be used as a regular expression is a properly formatted regular expression.
  • @Tainted and @Untainted – Identity types of data that should not be used together, such as remote user input being used in system commands, or sensitive information in log streams.
  • @m – Units of measure ensures that numbers used for measuring objects are used and compared correctly, or have undergone the proper unit conversion.

Putting Type Annotations on your code

Java SE 8 allows type annotations anywhere that a type is used. Previously, annotations were only allowed on definitions. Some examples of this are:

Annotation Example Meaning
@NonNull List<String>
A non-null list of Strings.
List<@NonNull String>
A list of non-null Strings.
@Regex String validation = "(Java|JDK) [7,8]"
Check at compile time that this String is a valid regular expression.
private String getInput(String parameterName){
final String retval = @Tainted request.getParameter(parameterName);
  return retval;
}
The object assigned to retval is tainted and not for use in sensitive operations.
private void runCommand(@Untainted String… commands){
ProcessBuilder processBuilder = new ProcessBuilder(command);
  Process process = processBuilder.start();
}
Each command must be untainted. For example, the previously tainted String must be validated before being passed in here.

For reading annotations, the way to look at them is that they annotate the next item after that isn’t also an annotation.

Automating issue detection

When working on software, it helps to uncover potential problems early. A problem caught early is easier to fix than one caught later, and a potential problem caught right away is easier still. Some annotations allow problems to be caught immediately. The @Override annotation allows the compiler (or a static analysis tool) to immediately determine if a developer wrote the wrong method signature.

Other annotations, like @NonNull and @Readonly can be used by analyzers like the Checker Framework, FindBugs, Eclipse, NetBeans, IntelliJ, or a commercial analyzer. Those analyzers can then be run at compile time, through IDE background compilation, Ant/Maven, or continuous integration.

Type Annotations tell those analyzers what to look for. Without the Type Annotations in place, these analyzers would still be able to locate null-usage and write-modifications but would not know that they are wrong. The result would then be false negatives (no issue reported) or false positives (incorrect issues reported).

Teamwork

Type Annotations can greatly benefit teams that are geographically distributed or contain many members. By placing Type Annotations inside the code and running automated checks before commits or during integration builds, team members can identify situations where one change inadvertently affects another.

Optional Type Annotations are not a substitute for runtime validation

Before Type Annotations, the primary location for describing things like nullability or ranges was in the javadoc. With Type annotations, this communication comes into the bytecode in a way for compile-time verification.

Your code should still perform runtime validation.

Annotation validation versus Business Validation

Type Annotations are best used with common forms of validation that relate to computer science. There are certain types of business validation that are not applicable.

Well-suited for Type Annotations
Likely not well-suited for Type Annotations
  • Null value checks.
  • Numeric range checks.
  • Basic type checks, such as regular expressions.
  • Assignments and updates (e.g. read-only)
  • Dataflow validation detection (e.g. have the incoming function arguments gone through the right validation functions)
  • This function cannot be executed outside certain hours or on government holidays.
  • Access to a feature requires a certain account-type.

Appendix

Annotations in core Java

There is no set of default type annotations available out of the box in the Java SE 8 platform. All previous examples in this post used the Checker Framework. The Type Annotations in Java SE 8 focused on the ability to put annotations in the right areas to describe a program. A separate, currently inactive JSR-305 (not part of Java 8) exists for identifying what those annotations should be.

The Checker Framework currently uses Java Annotation Index Files to gain comparable support for the core Java runtime and targeted libraries, or previous Java versions like Java SE 7 or 6.

Removal of APT

JDK 8 also removes a legacy annotation processing tool, named apt. Few users should be affected by this change. This was done as part of JEP 117 because everything required for annotation processing appears in either javax.annotation.processing or javax.lang.model.

Wednesday Mar 19, 2014

Java SE 8 is available for download

Developers and system administrators can now download the first official release of Java SE 8. This is the first major release since Java 7 (July 2011) and features significant improvements in speed, stability, and security. Complete details about Java SE 8 and launch events can be found at The Java Source and Mark’s blog.

Java 8 - Create the future

Please also join the main launch webinar on March 25.

New developers learning Java 8 may also view the Java Tutorials or focus on Java FX 8.

Coordinated Releases

The launch of Java SE 8 was a well-coordinated event across many lines of the Java community. Simultaneous support is available in all IDEs:

Many open source projects have also taken part in the quality outreach campaign. This work involved application compatibility testing as well as using the new JDeps utility to identify reliance on internal JDK APIs.

Auto-Updates and the Security Baseline

System Administrators or end-users looking at compatibility testing must explicitly download Java SE 8 from the Oracle Technology Network. End-users will not be auto-updated to Java SE 8, nor will it be available from Java.com until a future (currently undetermined) date.

The Security Baseline represents the latest critical patch update within its own family and is always documented within the latest release notes -- this baseline is separate for 8, 7, and 6.

Wednesday Mar 12, 2014

JavaOne 2014 Call for Proposals is open

The call for proposals to JavaOne 2014 is currently open. Those looking to speak may submit topics through the JavaOne website. This year’s conference takes place from September 28th through October 2nd in San Francisco.
There are several tracks for those wishing to speak. See the 2014 track listing for details.
  • Clients and UI
  • Core Java Platform
  • Internet of Things
  • Java Virtual Machine Languages
  • Java and Security
  • Tools and Techniques
  • Server-Side Java
  • Java in the Cloud
  • Agile Development
For inspiration, you may look at the list of sessions from JavaOne 2013 or sort the presentations by vote.

Thursday Feb 27, 2014

Managing multiple Java versions

The Java Platform provides various options for System Administrators to manage updates on client systems and maintain compatibility with specific applications

This post is intended to guide System Administrators whose clients make use of Rich Internet Applications (Applet & Web Start). Most of this does not apply to System Administrators of server-side applications or locally installed applications using the JRE.

The primary strategies for controlling RIA compatibility are:

  • Identify known RIAs.
  • Install Java versions through patch-in-place or static installation mode.
  • Deploy the latest version of Java.
  • Delegate certain RIAs to use specific Java versions.

Quick Example: A company has a back-office application for managing contractor timesheets. The application is known to require Java 6. The System Administrator should install the latest Java 7. After installation, the system administrator should statically-install the desired Java 6. The System Administrator should then create a Deployment Rule Set to indicate that a specific RIA requires Java 6.

Identify known RIAs

In order to whitelist RIAs and delegate certain RIAs to specific Java versions, the first step is to identify where those applications are. The two primary ways of doing this:

  • Location, the https:// or http:// or other protocol URL where the RIA is hosted and accessed by users. You will be able to wildcard these later. This is easiest when you control or host the destination, such as inside a company.
  • Code signing hash, an identifier of a vendor based on their public signing certificate. This can be easier when you have a number of RIAs from a particular vendor.

The way of identifying RIAs will vary between organizations. One important consideration is to provide a way that users can contact you with adjustments, for example reporting an RIA that you may have missed.

Install Java versions through patch-in-place or static installation mode

The JRE installation mechanism provides two types of installation: Patch-in-Place and Static Installation. The default mechanism is Patch-in-Place because it leaves a smaller footprint. It also intentionally does not leave older versions behind. Static Installation intentionally leaves behind the older version so that it can be used to execute specific RIAs.


Patch-In-Place Static Installation
Default: Yes No
Installation area: C:\Program Files\Java\jre7
Newer versions update this directory.
C:\Program Files\Java\jre1.7.0_##
Newer versions get their own directory.
Leaves older versions: No Yes
RIA Deployment Flow defaults to: The only version installed. The highest version installed.
Used for: Most cases Large environments where known applications require a specific older version of Java.

System Administrators can specify their preference when automating installation of the JRE.

In general, Patch-In-Place is the best default and you should use static installations only on systems known to require a specific version.

Deploy the latest version of Java

Users should always run the latest secure baseline. The latest version of Java always provides the best security defense and enterprise management features. For example, users needing to execute an RIA with Java 6 (end of public updates was in February 2013) should use the latest Java 7 version and let it delegate to Java 6 for the specific RIA.

Java installations contain two features to stay up to date: a security baseline and an expiration date. The security baseline represents the latest Critical Patch Update, whose schedule is published a year in advance. A separate "expiration date" is built-in for clients that cannot dynamically check this security baseline. The "expiration date" set at about a month after the scheduled critical patch and is documented at Java.com for the latest version as well as the Oracle Technology Network release notes for specific versions. Once a JRE detects that it is below the security baseline, it changes its behavior as described in the RIA Deployment Flow Guide.

The Deployment Flow process (including expiration date) can be controlled by delegating certain RIAs to use specific Java versions.

Delegate certain RIAs to use specific Java versions

The majority RIAs are compatible with the latest Java release within major versions. For example, an RIA that runs with JDK 1.7.0_01 is expected to be binary compatible with higher updates like JDK 1.7.0_51.

For specific applications where compatibility issues have been verified, System Administrators can use Deployment Rule Sets as a way of associating a specific RIA with a statically-installed Java version. When specifying a version for your DRS, it is easiest to go in order of: SECURE (no version), then SECURE-1.X (major version only), and only use specific versions like 1.7.0_51 for a verified compatibility issue. Because rules are specified explicitly by a system administrator, their results are applied before other checks that would affect program execution.

If you create any rules that DENY an RIA from running, it is a good idea to provide a way for users to contact you.

Deployment Rule Sets must be cryptographically signed. Commercial code-signing certificates are recommended but if you prefer to self-sign your Deployment Rule Set, you must distribute your public key to clients before they can recognize your signature.

The Deployment Rule Set files are installed to an area outside the Java installation directory and will remain active as clients update their Java installations.

For additional information, please see the complete Deployment Rule Set documentation.

Deployment Rule Set Version request

When specifying the version in a Deployment Rule Set, it is best to choose a version equal to or higher than the one requested by the launching JNLP file. If you specify a Java version below what the application says it needs then it is unlikely to run correctly.  Inside the JNLP file, there is a section that will look like <j2se version="1.X+" />

If the JNLP requests a version and you specify something below, then the application will be blocked.

If the JNLP requests a version and you specify something at or above, then it will run with what you have specified.

Specifying a version in your Deployment Rule Set that looks like SECURE or SECURE-1.X is often the simplest choice.

Tuesday Jan 28, 2014

JDK 8 will use TLS 1.2 as default

Transport Level Security (TLS) is designed to encrypt conversations between two parties and ensure that others can neither read nor modify the conversation. When combined with Certificate Authorities, a proper level of trust is established: we know who is on the other end of the conversation and that conversation is protected from eavesdropping/modification.

Support for TLS 1.2 first appeared in JDK 7 (2011). For compatibility reasons, it is enabled by default on server sockets but disabled on clients. Since that time, the industry has made considerable improvements to address interoperability and backwards compatibility.

We are setting JDK 8 to use TLS 1.2 as the default for two reasons:

  1. TLS is backwards-compatible. After upgrading the default to 1.2, systems using 1.1 and 1.0 will continue to function*.
    1. * Unless configured to use an algorithm that was removed for security reasons. Few systems are affected by this.
    2. For a complete description of TLS 1.2, please see RFC 5246.
    3. A quick summary of TLS/SSL differences is available from yaSSL.
  2. It strengthens the protection of internet communications against eavesdropping.

For those testing JDK 8 early access, this first occurred in build 122.

TLS is transparent to most users and developers. For those that would like more details, we will cover:

  • Threats and the role of encryption
  • Compatibility with the JDK and other systems
  • Understanding your TLS implementation
  • Other considerations for TLS

Threats and the role of encryption

With a new well-motivated IETF working group for encryption as well as wide industry support for TLS 1.2, the time is right to update system defaults.

Qualys SSL Labs has done great research in depicting a threat model for TLS. Their best practices in dealing with the TLS threat model (specifically "2.2 use secure protocols") support this move.

Compatibility with the JDK and other systems

TLS 1.2 is designed to be backwards-compatible as described in the RFC Appendix E (above). If a 1.2 client connects to a server running a lower version, the client will adjust. If a lower client connects to a server running 1.2, the server will adjust. Because of backwards-compatibility, clients supporting TLS 1.2 will receive improved communications and older clients will continue to function.
  • We added support for TLS 1.2 in JDK 7 (July 2011) although it was not the default. JDK 8 (March 2014) will use TLS 1.2 as the default.
  • OpenSSL added support for TLS 1.2 in version 1.0.1 (March 2012). Most Linux distributions and scripting languages use OpenSSL.
  • Microsoft supported TLS 1.2 in Windows 7. Internet Explorer and .NET follow accordingly. TLS 1.2 was first enabled by default in Internet Explorer 11 (October 2013).
  • Firefox turned TLS 1.2 on by default in version 27 (February 2014).
  • Chrome supported TLS 1.2 in version 29 (August 2013).
  • Etc.

Adoption statistics from the Trustworthy Internet's SSL Pulse show a sufficient number of internet-facing systems using TLS 1.2 and compatible ciphers.

Understanding your TLS implementation

Developers or System Administrators can test servers and clients through the Qualys SSL Labs (server or client) or a different How’s My SSL website.

System Administrators can view their system’s TLS implementation to monitor clients or disable specific TLS versions. For example some system administrators in highly sensitive businesses may want to disable older TLS versions from ever being used.

View your client’s version through a GUI

  1. Open the Java Control Panel
  2. Navigate to the Advanced tab.
  3. At the bottom, there is an “Advanced Security Settings.”
  4. Check or uncheck the "Use TLS X.Y" box.

On a server or without a GUI

  1. To set this for everything:
    1. Open the deployment.properties file, either user-level or system-level.
    2. Set the appropriate property
      deployment.security.TLSvX.Y=false
  2. To set for a specific application or script:
    1. Use the startup flag -Ddeployment.security.TLSvX.Y=false

Other Considerations for TLS

The InfoQ article, Keeping Your Secrets, covers additional information for developers looking to understand more about transport security and encryption. Outside the role of TLS protocol version, that article covers good techniques to safeguard information:

For System Administrators (or some Developers): Perfect Forward Secrecy can be used in Java TLS connections. Using Perfect Forward Secrecy protects past conversations: in the event that if keys are lost in the future, someone cannot decrypt past conversations. As is common with TLS implementations, Perfect Forward Secrecy is not enabled by default. Those that do want to use it can update their https.cipherSuites property. Common values for this property are:

  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
  • TLS_DHE_RSA_WITH_AES_128_CBC_SHA
  • Anything on the Algorithm Standard Name list that start with TLS (Transport Level Security) followed by a type of DHE (Diffie-Hellman Exchange).

Thursday Dec 12, 2013

Closing the closed APIs

Earlier this year, Wired published an article stating that, “Oracle has actually opened up Java even more — getting rid of some of the closed-door machinations that used to be part of the Java standards-making process.” This openness comes through OpenJDK and the Java Community Process, where different companies and developers all work together to guide the future of the Java Platform.

Part of opening Java involves dealing with the evolution of internal APIs in the JDK outside the actual Java Language specification and APIs. While developers should not be using internal APIs like sun.* packages, over the course of Java’s 18 year history, various applications have at times used these APIs for different reasons. Use of these implementation-specific, internal APIs poses challenges when they change and may decrease an application’s portability between different Java implementations . Given the ease of obtaining component libraries, we are looking at ways of identifying and mitigating usage of internal APIs in favor of APIs intended for public use.

I will cover several topics in dealing with these internal APIs:

  • Approach in identifying internal APIs
  • Current target: CORBA and Applets/SecurityManager
  • JDeps in Detail

Approach in identifying internal APIs

The definition of “internal API” is any package or class provided by a Java implementation that is not in the public API set. Gearing up for JDK8, OpenJDK contains a new tool called JDeps that is able to locate use of internal APIs within an application’s JAR files or bytecode. By running this tool, you can see which components use internal APIs and which internal APIs they use.

We have run JDeps against a number of applications to figure out popularity of internal APIs and understand any impact.

CORBA and Applets/SecurityManager

Starting in Java 7 update 51 (January 2014), we will move the internal undocumented com.sun.corba.se APIs into a restricted API list. This will affect applications only if they do all of three things:

  1. If your application uses restricted permissions (i.e. sandboxed RIA or runs with a SecurityManager)
  2. AND uses CORBA
  3. AND uses undocumented internal Sun APIs (com.sun.corba.se.*) to do it.

The first attempt at moving internal com.sun.corba.se APIs into a restricted API list came back in June of this year on the OpenJDK mailing list. After more reviews, a better patch was created in October. Beginning with Java 7 update 51, the internal CORBA APIs are entering into a restricted API list. This means that if you have an RIA using this internal API, your application will need the manifest entry "Permissions: all-permissions" and cannot use the sandbox. If your application specifies fine-grained permissions through the SecurityManager, then you will need the "accessClassInPackage.com.sun.corba.se" permission.

  • To see if your code or components use these internal CORBAP APIs, use JDeps and search the output for "com.sun.corba.se"
  • If the above JDeps output says that you are using the undocumented internal APIs, you have two options:
    1. Recommended: Update the code to use javax.rmi.CORBA or org.omg.* APIs instead of the otherwise undocumented internal APIs.
    2. Bide time by either using “Permissions: all-permissions” manifest entry in your applet or obtaining the "accessClassInPackage.com.sun.corba.se" permission from your SecurityManager. Please use any time gained to work on Option A, above.

JDeps in detail

OpenJDK 8 introduces a utility called JDeps that looks through JAR files and identifies which JAR files use internal APIs and then lists those APIs. This answers the questions, “am I using these internal classes” and “if so, which ones.” To use JDeps and check your applications, just download a preview release of JDK8. You do not need to actually test or run your application on JDK8, this just happens to be where the JDeps utility is.

You can then run JDeps on an application even if you do not have the source code.

To run JDeps against an application, the command looks like:

jdk8/bin/jdeps -P -jdkinternals *.jar > your-application.jdeps.txt

The output inside your-application.jdeps.txt will look like:

your.package (Filename.jar)
      -> com.sun.corba.se            JDK internal API (rt.jar)

Monday Nov 25, 2013

Upcoming Exception Site List in 7u51

Over the last year, many new security related features have been implemented. Many of those features have been related to browser plugins for applets and web start applications (RIAs). A number of end users and software vendors have asked for more ways to configure their environment and use of applications. 

The Exception Site List is a way for end-users to control their own application whitelist and continue using RIAs that could not be timely updated to follow previously announced security requirements. The Exception Site List provides a way to continue using a RIA but is not intended as a way to remove all warnings for the user. End-users will still see important prompts, but those prompts will no longer block.

Comparison to Deployment Rule Set

The introduction of the Exception Site List creates a second way for whitelisting RIAs and decreases requirements for system administrators.


 Exception Site List
Deployment Rule Set
 Introduced  Java 7 update 51 (January 2014)
Java 7 update 40 (September 2013)
 Intended for
 End-user System Administrator
 Formatted as
 Plain-text Signed JAR file
 If the two conflict with each-other
 Loses Wins

 For standard policy enforcement, some system administrators may lock down usage of the Exception Site List as they would with any other control panel setting.

Getting Early Access to the Exception Site List

Developers looking to test their applications in advance of 7u51 and use the Exception Site List can download early access of Java 7 update 60 over at the JDK 7 website. That website is the easiest way for developers to get early access of releases.

Adding a site to the Exception Site List

End-users can access the Exception Site List from the Java control panel.

  1. Use your browser to access the RIA that you normally use.
  2. Copy the URL from the address bar.
    Only choose directory paths ending in a / and not a filename.
    • Right: https://www.example.com/someApplication/
    • Wrong: https://www.example.com/someApplication/filename.html
  3. Open the Java control panel.
    • Windows/Mac - Open your system control panel or System Preferences and choose Java.
    • Linux/Solaris - Run the jcontrol command.
  4. Choose the Security tab.
  5. Click the "Manage Site List" button near the bottom.
  6. A new window will open.
    Screenshot of Exception Site List
  7. Click the Add button.
    Screenshot of adding an exception site
    • Right: https://www.example.com/someApplication/
    • Wrong: https://www.example.com/someApplication/filename.html
  8. Click OK. The window will close. You may see an additional prompt if you use an unencrypted protocol such as http or file. Choosing encrypted protocols defends against potential man-in-the-middle attacks.
  9. Back on the control panel, click OK to close it.
  10. Reload the web page on your browser to launch the RIA.

Files behind the Exception Site List

Update Jan 22: The Exception Site List is intended for end-users to create their own whitelist. If you are a System Administrator managing this across many machines, you will find the Deployment Rule Set much easier. Group Policy efforts are better used behind distributing a Deployment Rule Set. You can self-sign a DRS.

The Exception Site List is aimed towards end-users controlling their own Exception Site List.

The file controlling the Exception Site List is stored in the user’s deployment location as described in the deployment configuration. On my Windows 7 laptop, this location is C:\Users\ecostlow\AppData\LocalLow\Sun\Java\Deployment\security\exception.sites

The format is one site per line.

Sample customer support note

As changes are introduced, technical support representatives are usually asked for details. We will be creating a technical support note that can be downloaded and tweaked to help communicate this change to your customers. It is essentially a trimmed down version of this blog post with a stronger How-To message.

Update on Jan 14 2014: Here are the end-user instructions for using the Exception Site List. Otherwise if you need something more customizable, here is a sample Exception Site List support note. This is a docx file but it may appear as a zip.

Friday Nov 15, 2013

Security Resource Center

We recently launched a new Java security resource center on the Oracle Technology Network.The goal of this page is to aggregate security-related information for members of the Java community based on their roles.

The resource center is not meant for specific technical features. Features are different and well covered in documentation sections like cryptography. The resource center focuses more towards "security is everyone's responsibility" in discussing how features and people work together.

One of the first items added to the security resource center is an RIA Checklist that developers and managers can use to accommodate previously announced changes in Java 7 update 51 (January 2014).

Monday Nov 11, 2013

Self-signed certificates for a known community

Recently announced changes scheduled for Java 7 update 51 (January 2014) have established that the default security slider will require code signatures and the Permissions Manifest attribute. Code signatures are a common practice recommended in the industry because they help determine that the code your computer will run is the same code that the publisher created.

This post is written to help users that need to use self-signed certificates without involving a public Certificate Authority.

The role of self-signed certificates within a known community

You may still use self-signed certificates within a known community. The difference between self-signed and purchased-from-CA is that your users must import your self-signed certificate to indicate that it is valid, whereas Certificate Authorities are already trusted by default.

This works for known communities where people will trust that my certificate is mine, but does not scale widely where I cannot actually contact or know the systems that will need to trust my certificate. Public Certificate Authorities are widely trusted already because they abide by many different requirements and frequent checks.

An example would be students in a university class sharing their public certificates on a mailing list or web page, employees publishing on the intranet, or a system administrator rolling certificates out to end-users. Managed machines help this because you can automate the rollout, but they are not required -- the major point simply that people will trust and import your certificate.

How to distribute self-signed certificates for a known community

There are several steps required to distribute a self-signed certificate to users so that they will properly trust it. These steps are:

  1. Creating a public/private key pair for signing.
  2. Exporting your public certificate for others
  3. Importing your certificate onto machines that should trust you
  4. Verify work on a different machine

Creating a public/private key pair for signing

Having a public/private key pair will give you the ability both to sign items yourself and issue a Certificate Signing Request (CSR) to a certificate authority.

Create your public/private key pair by following the instructions for creating key pairs.
Every Certificate Authority that I looked at provided similar instructions, but for the sake of cohesiveness I will include the commands that I used here:

  1. Generate the key pair.
    keytool -genkeypair -alias erikcostlow -keyalg EC -keysize 571 -validity 730 -keystore javakeystore_keepsecret.jks
    • Provide a good password for this file.
    • The alias "erikcostlow" is my name and therefore easy to remember. Substitute your name of something like "mykey."
    • The sigalg of EC (Elliptical Curve) and keysize of 571 will give your key a good strong lifetime.
    • All keys are set to expire. Two years or 730 days is a reasonable compromise between not-long-enough and too-long. Most public Certificate Authorities will sign something for one to five years.
    • You will be placing your keys in javakeystore_keepsecret.jks -- this file will contain private keys and therefore should not be shared. If someone else gets these private keys, they can impersonate your signature. Please be cautious about automated cloud backup systems and private key stores.
  2. Answer all the questions. It is important to provide good answers because you will stick with them for the "-validity" days that you specified above.
    What is your first and last name?
      [Unknown]:  First Last
    What is the name of your organizational unit?
      [Unknown]:  Line of Business
    What is the name of your organization?
      [Unknown]:  MyCompany
    What is the name of your City or Locality?
      [Unknown]:  City Name
    What is the name of your State or Province?
      [Unknown]:  CA
    What is the two-letter country code for this unit?
      [Unknown]:  US
    Is CN=First Last, OU=Line of Business, O=MyCompany, L=City, ST=CA, C=US correct?
      [no]:  yes
    Enter key password for <erikcostlow>
            (RETURN if same as keystore password):
  3. Verify your work:
    keytool -list -keystore javakeystore_keepsecret.jks
    You should see your new key pair.

Exporting your public certificate for others

Public Key Infrastructure relies on two simple concepts: the public key may be made public and the private key must be private. By exporting your public certificate, you are able to share it with others who can then import the certificate to trust you.

keytool -exportcert -keystore javakeystore_keepsecret.jks -alias erikcostlow -file erikcostlow.cer

To verify this, you can open the .cer file by double-clicking it on most operating systems. It should show the information that you entered during the creation prompts.

This is the file that you will share with others. They will use this certificate to prove that artifacts signed by this certificate came from you. If you do not manage machines directly, place the certificate file on an area that people within the known community should trust, such as an intranet page.

Import the certificate onto machines that should trust you

In order to trust the certificate, people within your known network must import your certificate into their keystores. The first step is to verify that the certificate is actually yours, which can be done through any band: email, phone, in-person, etc. Known networks can usually do this

Determine the right keystore:

  • For an individual user looking to trust another, the correct file is within that user’s directory.
    e.g. USER_HOME\AppData\LocalLow\Sun\Java\Deployment\security\trusted.certs
    The default password for trusted.certs is an empty string.
  • For system-wide installations, Java’s Certificate Authorities are in JAVA_HOME
    e.g. C:\Program Files\Java\jre8\lib\security\cacerts
    The default password for cacerts is "changeit" as described in the keytool documentation.

File paths for Mac and Linux are included in the link above.

Follow the instructions to import the certificate into the keystore.

keytool -importcert -keystore THEKEYSTOREFROMABOVE -alias erikcostlow -file erikcostlow.cer

In this case, I am still using my name for the alias because it’s easy for me to remember. You may also use an alias of your company name.

Scaling distribution of the import

The easiest way to apply your certificate across many machines is to just push the .certs or cacerts file onto them. When doing this, watch out for any changes that people would have made to this file on their machines.

Trusted.certs: When publishing into user directories, your file will overwrite any keys that the user has added since last update.

CACerts: It is best to re-run the import command with each installation rather than just overwriting the file. If you just keep the same cacerts file between upgrades, you will overwrite any CAs that have been added or removed. By re-importing, you stay up to date with changes.

There is a -storepass argument for specifying the password on the command-line. On secure systems, admins typically hide passwords through redirection operators but that's outside the scope of this post.

Verify work on a different machine

Verification is a way of checking on the client machine to ensure that it properly trusts signed artifacts after you have added your signing certificate. Many people have started using deployment rule sets. You can validate the deployment rule set by:

  1. Create and sign the deployment rule set on the computer that holds the private key.
  2. Copy the deployment rule set on to the different machine where you have imported the signing certificate.
  3. Verify that the Java Control Panel’s security tab shows your deployment rule set.

Verifying an individual JAR file or multiple JAR files

You can test a certificate chain by using the jarsigner command.

jarsigner -verify filename.jar

If the output does not say "jar verified" then run the following command to see why:

jarsigner -verify -verbose -certs filename.jar

Check the output for the term “CertPath not validated.”

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
  • Oracle
Archives
« July 2014
SunMonTueWedThuFriSat
  
1
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today